From 6bc89b41c700426b4e9d6591d4289b86ce1fbaae Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Wed, 4 Mar 2026 10:38:40 -0600 Subject: [PATCH 01/17] stash --- package-lock.json | 372 +++++++++++++----- .../src/table-column/base/index.ts | 3 + packages/nimble-components/src/table/index.ts | 9 +- .../src/table/models/table-layout-manager.ts | 2 +- .../src/table/models/table-update-tracker.ts | 10 +- .../nimble-components/src/table/template.ts | 22 ++ 6 files changed, 309 insertions(+), 109 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72fbd654a3..181c6e5371 100644 --- a/package-lock.json +++ b/package-lock.json @@ -230,6 +230,7 @@ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12.0.0" }, @@ -253,6 +254,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -298,7 +300,6 @@ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -335,6 +336,7 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -424,6 +426,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -543,6 +546,7 @@ "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-19.8.1.tgz", "integrity": "sha512-NOMkw0xgDoDVCLkL5nkkvdd3ouDYkOGqtEmabTR7N4/kQnk1R4coOTWGCqAgMXCFdxlyjuxquDwuJ+yni81pRg==", "license": "MIT", + "peer": true, "dependencies": { "@angular-devkit/architect": ">= 0.1900.0 < 0.2000.0", "@angular-devkit/core": ">= 19.0.0 < 20.0.0" @@ -556,13 +560,15 @@ "version": "19.8.1", "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-19.8.1.tgz", "integrity": "sha512-WXi1YbSs7SIQo48u+fCcc5Nt14/T4QzYQPLZUnjtsUXPgQG7ZoahhcGf7PPQ+n0V3pSopHOlSHwqK+tSsYK87A==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@angular-eslint/eslint-plugin": { "version": "19.8.1", "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-19.8.1.tgz", "integrity": "sha512-wZEBMPwD2TRhifG751hcj137EMIEaFmsxRB2EI+vfINCgPnFGSGGOHXqi8aInn9fXqHs7VbXkAzXYdBsvy1m4Q==", "license": "MIT", + "peer": true, "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.8.1", "@angular-eslint/utils": "19.8.1" @@ -578,6 +584,7 @@ "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-19.8.1.tgz", "integrity": "sha512-0ZVQldndLrDfB0tzFe/uIwvkUcakw8qGxvkEU0l7kSbv/ngNQ/qrkRi7P64otB15inIDUNZI2jtmVat52dqSfQ==", "license": "MIT", + "peer": true, "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.8.1", "@angular-eslint/utils": "19.8.1", @@ -597,6 +604,7 @@ "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-19.8.1.tgz", "integrity": "sha512-MKzfO3puOCuQFgP8XDUkEr5eaqcCQLAdYLLMcywEO/iRs1eRHL46+rkW+SjDp1cUqlxKtu+rLiTYr0T/O4fi9Q==", "license": "MIT", + "peer": true, "dependencies": { "@angular-devkit/core": ">= 19.0.0 < 20.0.0", "@angular-devkit/schematics": ">= 19.0.0 < 20.0.0", @@ -612,6 +620,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "license": "MIT", + "peer": true, "engines": { "node": ">= 4" } @@ -621,6 +630,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "license": "ISC", + "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -648,6 +658,7 @@ "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-19.8.1.tgz", "integrity": "sha512-gVDKYWmAjeTPtaYmddT/HS03fCebXJtrk8G1MouQIviZbHqLjap6TbVlzlkBigRzaF0WnFnrDduQslkJzEdceA==", "license": "MIT", + "peer": true, "dependencies": { "@angular-eslint/bundled-angular-compiler": "19.8.1" }, @@ -662,7 +673,6 @@ "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.2.18.tgz", "integrity": "sha512-c76x1t+OiSstPsvJdHmV8Q4taF+8SxWKqiY750fOjpd01it4jJbU6YQqIroC6Xie7154zZIxOTHH2uTj+nm5qA==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1057,7 +1067,6 @@ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -1123,7 +1132,6 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -1564,7 +1572,6 @@ "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.18.tgz", "integrity": "sha512-CrV02Omzw/QtfjlEVXVPJVXipdx83NuA+qSASZYrxrhKFusUZyK3P/Zznqg+wiAeNDbedQwMUVqoAARHf0xQrw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1581,7 +1588,6 @@ "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.18.tgz", "integrity": "sha512-3MscvODxRVxc3Cs0ZlHI5Pk5rEvE80otfvxZTMksOZuPlv1B+S8MjWfc3X3jk9SbyUEzODBEH55iCaBHD48V3g==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1594,7 +1600,6 @@ "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.18.tgz", "integrity": "sha512-N4TMtLfImJIoMaRL6mx7885UBeQidywptHH6ACZj71Ar6++DBc1mMlcwuvbeJCd3r3y8MQ5nLv5PZSN/tHr13w==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "7.26.9", "@jridgewell/sourcemap-codec": "^1.4.14", @@ -1668,7 +1673,6 @@ "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.2.18.tgz", "integrity": "sha512-+QRrf0Igt8ccUWXHA+7doK5W6ODyhHdqVyblSlcQ8OciwkzIIGGEYNZom5OZyWMh+oI54lcSeyV2O3xaDepSrQ==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1685,7 +1689,6 @@ "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.2.18.tgz", "integrity": "sha512-pe40934jWhoS7DyGl7jyZdoj1gvBgur2t1zrJD+csEkTitYnW14+La2Pv6SW1pNX5nIzFsgsS9Nex1KcH5S6Tw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1704,7 +1707,6 @@ "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-19.2.18.tgz", "integrity": "sha512-FEZLbpFgCyoRB5Qv30msDb1tJYpwwmkrQTOUUdcB6j0RjHDiSe9jEsArC2Qy0glofjzu9cPoBOcdxY5UocBvdg==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "7.26.9", "@types/babel__core": "7.20.5", @@ -1774,7 +1776,6 @@ "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.18.tgz", "integrity": "sha512-eahtsHPyXTYLARs9YOlXhnXGgzw0wcyOcDkBvNWK/3lA0NHIgIHmQgXAmBo+cJ+g9skiEQTD2OmSrrwbFKWJkw==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1815,7 +1816,6 @@ "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.2.18.tgz", "integrity": "sha512-7cimxtPODSwokFQ0TRYzX0ad8Yjrl0MJfzaDCJejd1n/q7RZ7KZmHd0DS/LkDNXVMEh4swr00fK+3YWG/Szsrg==", "license": "MIT", - "peer": true, "dependencies": { "tslib": "^2.3.0" }, @@ -1857,7 +1857,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", @@ -3945,6 +3944,7 @@ "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" @@ -3956,6 +3956,7 @@ "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -3966,6 +3967,7 @@ "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -3981,6 +3983,7 @@ "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.71.0.tgz", "integrity": "sha512-2p9+dXWNQnp5Kq/V0XVWZiVAabzlX6rUW8vXXvtX8Yc1CkKgD93IPDEnv1sYZFkkS6HMvg6H0RMZfob/Co0YXA==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "^1.0.8", "@typescript-eslint/types": "^8.46.0", @@ -4414,6 +4417,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "license": "MIT", + "peer": true, "dependencies": { "eslint-visitor-keys": "^3.4.3" }, @@ -4432,6 +4436,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "license": "Apache-2.0", + "peer": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -4444,6 +4449,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "license": "MIT", + "peer": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -4453,6 +4459,7 @@ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", @@ -4467,6 +4474,7 @@ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@eslint/core": "^0.17.0" }, @@ -4479,6 +4487,7 @@ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@types/json-schema": "^7.0.15" }, @@ -4491,6 +4500,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "license": "MIT", + "peer": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -4514,6 +4524,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4529,13 +4540,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@eslint/js": { "version": "9.39.2", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", "license": "MIT", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -4572,6 +4585,7 @@ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -4581,6 +4595,7 @@ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" @@ -4650,6 +4665,7 @@ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=18.18.0" } @@ -4659,6 +4675,7 @@ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" @@ -4672,6 +4689,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=12.22" }, @@ -4685,6 +4703,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">=18.18" }, @@ -4942,7 +4961,6 @@ "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@inquirer/checkbox": "^4.1.2", "@inquirer/confirm": "^5.1.6", @@ -6125,6 +6143,7 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/shared/-/shared-3.0.2.tgz", "integrity": "sha512-anFGls154h0iVzUt5O43EaqYvPwzfUxQ34QpNQsUQML7pbEJMhcgkRNvYw9hZBspab+/TP45agdPw5joh6/BBA==", "license": "MIT", + "peer": true, "dependencies": { "@mdit-vue/types": "3.0.2", "@types/markdown-it": "^14.1.2", @@ -6139,6 +6158,7 @@ "resolved": "https://registry.npmjs.org/@mdit-vue/types/-/types-3.0.2.tgz", "integrity": "sha512-00aAZ0F0NLik6I6Yba2emGbHLxv+QYrPH00qQ5dFKXlAo1Ll2RHDXwY7nN2WAfrx2pP+WrvSRFTGFCNGdzBDHw==", "license": "MIT", + "peer": true, "engines": { "node": ">=20.0.0" } @@ -6574,6 +6594,7 @@ "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", @@ -6641,7 +6662,6 @@ "resolved": "https://registry.npmjs.org/@ni/eslint-config-angular/-/eslint-config-angular-11.1.0.tgz", "integrity": "sha512-coaIf0cI5K01F1k5BtZ5YVeq6olM1H8GYeGGA9EwPDr31b1yrXL4lqh8wjSV/gf7dIpNfFdBBM1U+bmdMc5pww==", "license": "MIT", - "peer": true, "peerDependencies": { "@ni/eslint-config-javascript": "^5.1.4", "@ni/eslint-config-typescript": "^5.0.5", @@ -6653,7 +6673,6 @@ "resolved": "https://registry.npmjs.org/@ni/eslint-config-javascript/-/eslint-config-javascript-5.1.4.tgz", "integrity": "sha512-UvWMiPlRmTqS4GH4efxP/M6R2Mw2IEBpibgVSMU/0vrPqhs32BBKoIyewTPrMcxNEA0EAMYZETQqK+g5WrskgQ==", "license": "MIT", - "peer": true, "peerDependencies": { "@stylistic/eslint-plugin": "^5.4.0", "eslint": "^9.36.0", @@ -7221,6 +7240,7 @@ "hasInstallScript": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "detect-libc": "^2.0.3", "is-glob": "^4.0.3", @@ -7263,6 +7283,7 @@ "os": [ "android" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7284,6 +7305,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7305,6 +7327,7 @@ "os": [ "darwin" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7326,6 +7349,7 @@ "os": [ "freebsd" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7347,6 +7371,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7368,6 +7393,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7389,6 +7415,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7410,6 +7437,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7431,6 +7459,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7452,6 +7481,7 @@ "os": [ "linux" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7473,6 +7503,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7494,6 +7525,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7515,6 +7547,7 @@ "os": [ "win32" ], + "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -7529,7 +7562,8 @@ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true, "license": "MIT", - "optional": true + "optional": true, + "peer": true }, "node_modules/@parcel/watcher/node_modules/picomatch": { "version": "4.0.3", @@ -7538,6 +7572,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -7572,6 +7607,7 @@ "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", "license": "MIT", + "peer": true, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" }, @@ -7605,7 +7641,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-rc.2", @@ -7665,7 +7702,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -8202,7 +8238,8 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@schematics/angular": { "version": "19.2.19", @@ -8641,6 +8678,7 @@ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.8.0.tgz", "integrity": "sha512-WNPVF/FfBAjyi3OA7gok8swRiImNLKI4dmV3iK/GC/0xSJR7eCzBFsw9hLZVgb1+MYNLy7aDsjohxN1hA/FIfQ==", "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/types": "^8.54.0", @@ -8661,6 +8699,7 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -8932,6 +8971,7 @@ "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -8951,6 +8991,7 @@ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "license": "Apache-2.0", + "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -8998,7 +9039,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-3.19.0.tgz", "integrity": "sha512-bpqELwPW+DG8gWiD8iiFtSl4vIBooG5uVJod92Qxn3rA9nFatyXRr4kNbMJmOZ66ezUvmCjXVe/5/G4i5cyzKA==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -9181,7 +9221,6 @@ "resolved": "https://registry.npmjs.org/@tiptap/suggestion/-/suggestion-3.19.0.tgz", "integrity": "sha512-tUZwMRFqTVPIo566ZmHNRteyZxJy2EE4FA+S3IeIUOOvY6AW0h1imhbpBO7sXV8CeEQvpa+2DWwLvy7L3vmstA==", "license": "MIT", - "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/ueberdosis" @@ -9264,6 +9303,7 @@ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "license": "MIT", "optional": true, + "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -9272,7 +9312,8 @@ "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -9350,13 +9391,15 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/@types/command-line-args/-/command-line-args-5.2.3.tgz", "integrity": "sha512-uv0aG6R0Y8WHZLTamZwtfsDLVRnOa+n+n5rEvFWL5Na5gZ8V2Teab/duDPFzIIIhs9qizDpcavCusCLJZu62Kw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/command-line-usage": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/command-line-usage/-/command-line-usage-5.0.4.tgz", "integrity": "sha512-BwR5KP3Es/CSht0xqBcUXS3qCAUVXwpRKsV2+arxeb65atasuXG9LykC9Ab10Cw3s2raH92ZqOeILaQbsB2ACg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/connect": { "version": "3.4.38", @@ -9576,13 +9619,15 @@ "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/katex": { "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.8.tgz", "integrity": "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/linkify-it": { "version": "5.0.0", @@ -9641,7 +9686,6 @@ "integrity": "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -9703,7 +9747,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.13.tgz", "integrity": "sha512-KkiJeU6VbYbUOp5ITMIc7kBfqlYkKA5KhEHVrGMmUUMt7NeaZg65ojdPk+FtNrBAOXNVM5QM72jnADjM+XVRAQ==", "license": "MIT", - "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -9841,6 +9884,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.55.0", @@ -9869,6 +9913,7 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "license": "MIT", + "peer": true, "engines": { "node": ">= 4" } @@ -9903,6 +9948,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.55.0", "@typescript-eslint/types": "^8.55.0", @@ -9924,6 +9970,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "8.55.0", "@typescript-eslint/visitor-keys": "8.55.0" @@ -9941,6 +9988,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", "license": "MIT", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -9957,6 +10005,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "8.55.0", "@typescript-eslint/typescript-estree": "8.55.0", @@ -9995,6 +10044,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/project-service": "8.55.0", "@typescript-eslint/tsconfig-utils": "8.55.0", @@ -10022,6 +10072,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -10031,6 +10082,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10070,6 +10122,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/types": "8.55.0", "eslint-visitor-keys": "^4.2.1" @@ -10093,7 +10146,8 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-android-arm64": { "version": "1.11.1", @@ -10106,7 +10160,8 @@ "optional": true, "os": [ "android" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-darwin-arm64": { "version": "1.11.1", @@ -10119,7 +10174,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-darwin-x64": { "version": "1.11.1", @@ -10132,7 +10188,8 @@ "optional": true, "os": [ "darwin" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-freebsd-x64": { "version": "1.11.1", @@ -10145,7 +10202,8 @@ "optional": true, "os": [ "freebsd" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { "version": "1.11.1", @@ -10158,7 +10216,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { "version": "1.11.1", @@ -10171,7 +10230,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { "version": "1.11.1", @@ -10184,7 +10244,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { "version": "1.11.1", @@ -10197,7 +10258,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { "version": "1.11.1", @@ -10210,7 +10272,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { "version": "1.11.1", @@ -10223,7 +10286,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { "version": "1.11.1", @@ -10236,7 +10300,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { "version": "1.11.1", @@ -10249,7 +10314,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { "version": "1.11.1", @@ -10262,7 +10328,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { "version": "1.11.1", @@ -10275,7 +10342,8 @@ "optional": true, "os": [ "linux" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { "version": "1.11.1", @@ -10286,6 +10354,7 @@ ], "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@napi-rs/wasm-runtime": "^0.2.11" }, @@ -10304,7 +10373,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { "version": "1.11.1", @@ -10317,7 +10387,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { "version": "1.11.1", @@ -10330,7 +10401,8 @@ "optional": true, "os": [ "win32" - ] + ], + "peer": true }, "node_modules/@vitejs/plugin-react-swc": { "version": "4.2.3", @@ -10636,7 +10708,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -10649,6 +10720,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "license": "MIT", + "peer": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -10697,7 +10769,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -10838,6 +10909,7 @@ "resolved": "https://registry.npmjs.org/apache-arrow/-/apache-arrow-21.1.0.tgz", "integrity": "sha512-kQrYLxhC+NTVVZ4CCzGF6L/uPVOzJmD1T3XgbiUnP7oTeVFOFgEUu6IKNwCDkpFoBVqDKQivlX4RUFqqnWFlEA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@swc/helpers": "^0.5.11", "@types/command-line-args": "^5.2.3", @@ -10858,6 +10930,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.13.tgz", "integrity": "sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -10867,6 +10940,7 @@ "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", "license": "MIT", + "peer": true, "engines": { "node": ">=14" } @@ -10891,6 +10965,7 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.2.tgz", "integrity": "sha512-gUAZ7HPyb4SJczXAMUXMGAvI976JoK3qEx9v1FTmeYuJj0IBiaKttG1ydtGKdkfqWkIkouke7nG8ufGy77+Cvw==", "license": "MIT", + "peer": true, "engines": { "node": ">=12.17" } @@ -10976,6 +11051,7 @@ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", "license": "MIT", + "peer": true, "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.4", @@ -11179,6 +11255,7 @@ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "license": "Apache-2.0", + "peer": true, "engines": { "node": ">= 0.4" } @@ -11641,7 +11718,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -12078,6 +12154,7 @@ "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", "license": "MIT", + "peer": true, "dependencies": { "chalk": "^4.1.2" }, @@ -12540,6 +12617,7 @@ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-6.0.1.tgz", "integrity": "sha512-Jr3eByUjqyK0qd8W0SGFW1nZwqCaNCtbXjRo2cRJC1OYxWl3MZ5t1US3jq+cO4sPavqgw4l9BMGX0CBe+trepg==", "license": "MIT", + "peer": true, "dependencies": { "array-back": "^6.2.2", "find-replace": "^5.0.2", @@ -12563,6 +12641,7 @@ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-7.0.3.tgz", "integrity": "sha512-PqMLy5+YGwhMh1wS04mVG44oqDsgyLRSKJBdOo1bnYhMKBW65gZF1dRp2OZRhiTjgUHljy99qkO7bsctLaw35Q==", "license": "MIT", + "peer": true, "dependencies": { "array-back": "^6.2.2", "chalk-template": "^0.4.0", @@ -12588,6 +12667,7 @@ "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "license": "MIT", + "peer": true, "engines": { "node": ">= 12.0.0" } @@ -13127,14 +13207,14 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/cross-env": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==", "license": "MIT", - "peer": true, "dependencies": { "@epic-web/invariant": "^1.0.0", "cross-spawn": "^7.0.6" @@ -13429,7 +13509,6 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } @@ -13633,7 +13712,8 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/deepmerge": { "version": "4.3.1", @@ -13822,8 +13902,7 @@ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1467305.tgz", "integrity": "sha512-LxwMLqBoPPGpMdRL4NkLFRNy3QLp6Uqa7GNp1v6JaBheop2QrB9Q7q0A/q/CYYP9sBfZdHOyszVx4gc9zyk7ow==", "dev": true, - "license": "BSD-3-Clause", - "peer": true + "license": "BSD-3-Clause" }, "node_modules/di": { "version": "0.0.1", @@ -13837,6 +13916,7 @@ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "license": "MIT", + "peer": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -13883,7 +13963,8 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/dom-serialize": { "version": "2.2.1", @@ -14070,6 +14151,7 @@ "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz", "integrity": "sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==", "license": "MIT", + "peer": true, "engines": { "node": ">=10.0.0" } @@ -14288,6 +14370,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "prr": "~1.0.1" }, @@ -14670,6 +14753,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", "license": "MIT", + "peer": true, "dependencies": { "get-tsconfig": "^4.10.1", "stable-hash-x": "^0.2.0" @@ -14694,6 +14778,7 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "license": "MIT", + "peer": true, "dependencies": { "debug": "^3.2.7", "is-core-module": "^2.13.0", @@ -14705,6 +14790,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -14749,6 +14835,7 @@ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", "license": "MIT", + "peer": true, "dependencies": { "debug": "^3.2.7" }, @@ -14766,6 +14853,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -14809,6 +14897,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", + "peer": true, "dependencies": { "ms": "^2.1.1" } @@ -14818,6 +14907,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", + "peer": true, "bin": { "semver": "bin/semver.js" } @@ -14827,6 +14917,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-60.8.3.tgz", "integrity": "sha512-4191bTMvnd5WUtopCdzNhQchvv/MxtPD86ZGl3vem8Ibm22xJhKuIyClmgSxw+YERtorVc/NhG+bGjfFVa6+VQ==", "license": "BSD-3-Clause", + "peer": true, "dependencies": { "@es-joy/jsdoccomment": "~0.71.0", "are-docs-informative": "^0.0.2", @@ -14853,6 +14944,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -14865,6 +14957,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-markdown-links/-/eslint-plugin-markdown-links-0.7.1.tgz", "integrity": "sha512-c6HAhdS3GmNLOzEuauGZ1+kkr20ruAHuF5rzwT48PdfZLTvPLeXa1Mb6HLdG8koLvwiLaIsXd8CntO/dt6UZug==", "license": "MIT", + "peer": true, "dependencies": { "@mdit-vue/shared": "^3.0.2", "entities": "^7.0.0", @@ -14890,6 +14983,7 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", "license": "BSD-2-Clause", + "peer": true, "engines": { "node": ">=0.12" }, @@ -15039,6 +15133,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -15055,6 +15150,7 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "license": "Apache-2.0", + "peer": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -15067,6 +15163,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -15083,6 +15180,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -15095,6 +15193,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "license": "ISC", + "peer": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -15106,13 +15205,15 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/espree": { "version": "10.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", @@ -15143,6 +15244,7 @@ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "license": "BSD-3-Clause", + "peer": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -15431,7 +15533,8 @@ "url": "https://opencollective.com/fastify" } ], - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-deep-equal": { "version": "3.1.3", @@ -15466,13 +15569,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/fast-uri": { "version": "3.1.0", @@ -15504,6 +15609,7 @@ "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", "license": "MIT", + "peer": true, "dependencies": { "format": "^0.2.0" }, @@ -15553,6 +15659,7 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "license": "MIT", + "peer": true, "dependencies": { "flat-cache": "^4.0.0" }, @@ -15640,6 +15747,7 @@ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-5.0.2.tgz", "integrity": "sha512-Y45BAiE3mz2QsrN2fb5QEtO4qb44NcS7en/0y9PEVsg351HsLeVclP8QPMH79Le9sH3rs5RSwJu99W0WPZO43Q==", "license": "MIT", + "peer": true, "engines": { "node": ">=14" }, @@ -15657,6 +15765,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "license": "MIT", + "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -15693,6 +15802,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "license": "MIT", + "peer": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -15705,7 +15815,8 @@ "version": "25.9.23", "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/flatted": { "version": "3.3.3", @@ -16040,6 +16151,7 @@ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", "license": "MIT", + "peer": true, "dependencies": { "resolve-pkg-maps": "^1.0.0" }, @@ -16087,7 +16199,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", - "license": "ISC" + "license": "ISC", + "peer": true }, "node_modules/glob": { "version": "11.1.0", @@ -16171,7 +16284,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -16492,7 +16604,8 @@ "url": "https://patreon.com/mdevils" } ], - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/html-escaper": { "version": "2.0.2", @@ -16772,6 +16885,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "bin": { "image-size": "bin/image-size.js" }, @@ -17260,6 +17374,7 @@ "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", "license": "MIT", + "peer": true, "dependencies": { "semver": "^7.7.1" } @@ -18008,8 +18123,7 @@ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.13.0.tgz", "integrity": "sha512-vsYjfh7lyqvZX5QgqKc4YH8phs7g96Z8bsdIFNEU3VqXhlHaq+vov/Fgn/sr6MiUczdZkyXRC3TX369Ll4Nzbw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/jasmine/node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -18210,7 +18324,6 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "devOptional": true, "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -18496,6 +18609,7 @@ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-6.6.0.tgz", "integrity": "sha512-3hSD14nXx66Rspx1RMnz1Pj4JacrMBAsC0CrF9lZYO/Qsp5/oIr6KqujVUNhQu94B6mMip2ukki8MpEWZwyhKA==", "license": "MIT", + "peer": true, "engines": { "node": ">=20.0.0" } @@ -18516,6 +18630,7 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz", "integrity": "sha512-2WHyXj3OfHSgNyuzDbSxI1w2jgw5gkWSWhS7Qg4bWXx1nLk3jnbwfUeS0PSba3IzpTUWdHxBieELUzXRjQB2zg==", + "peer": true, "engines": { "node": ">=0.8" } @@ -18524,7 +18639,8 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -18563,7 +18679,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/json5": { "version": "2.2.3", @@ -18638,7 +18755,6 @@ "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@colors/colors": "1.5.0", "body-parser": "^1.19.0", @@ -18773,7 +18889,6 @@ "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "jasmine-core": "^4.1.0" }, @@ -19080,6 +19195,7 @@ "https://github.com/sponsors/katex" ], "license": "MIT", + "peer": true, "dependencies": { "commander": "^8.3.0" }, @@ -19092,6 +19208,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "license": "MIT", + "peer": true, "engines": { "node": ">= 12" } @@ -19101,6 +19218,7 @@ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "license": "MIT", + "peer": true, "dependencies": { "json-buffer": "3.0.1" } @@ -19159,7 +19277,6 @@ "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "copy-anything": "^2.0.1", "parse-node-version": "^1.0.1", @@ -19215,6 +19332,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "bin": { "mime": "cli.js" }, @@ -19229,6 +19347,7 @@ "dev": true, "license": "BSD-3-Clause", "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -19238,6 +19357,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "license": "MIT", + "peer": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -19617,6 +19737,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", + "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -19665,7 +19786,8 @@ "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/lodash.snakecase": { "version": "4.1.1", @@ -19973,6 +20095,7 @@ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "license": "MIT", + "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -20143,6 +20266,7 @@ "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", "license": "MIT", + "peer": true, "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -20161,6 +20285,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -20274,6 +20399,7 @@ "resolved": "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-3.0.0.tgz", "integrity": "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==", "license": "MIT", + "peer": true, "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -20506,6 +20632,7 @@ "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", "license": "MIT", + "peer": true, "dependencies": { "fault": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -20643,6 +20770,7 @@ "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", "license": "MIT", + "peer": true, "dependencies": { "@types/katex": "^0.16.0", "devlop": "^1.0.0", @@ -21439,6 +21567,7 @@ "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "license": "MIT", + "peer": true, "bin": { "napi-postinstall": "lib/cli.js" }, @@ -21453,7 +21582,8 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/needle": { "version": "3.3.1", @@ -21462,6 +21592,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "iconv-lite": "^0.6.3", "sax": "^1.2.4" @@ -21480,6 +21611,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -21520,7 +21652,6 @@ "integrity": "sha512-dFuwFsDJMBSd1YtmLLcX5bNNUCQUlRqgf34aXA+79PmkOP+0eF8GP2949wq3+jMjmFTNm80Oo8IUYiSLwklKCQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rollup/plugin-json": "^6.1.0", "@rollup/wasm-node": "^4.24.0", @@ -22060,6 +22191,7 @@ "resolved": "https://registry.npmjs.org/object-deep-merge/-/object-deep-merge-1.0.5.tgz", "integrity": "sha512-3DioFgOzetbxbeUq8pB2NunXo8V0n4EvqsWM/cJoI6IA9zghd7cl/2pBOuWRf4dlvA+fcg5ugFMZaN2/RuoaGg==", "license": "MIT", + "peer": true, "dependencies": { "type-fest": "4.2.0" } @@ -22161,6 +22293,7 @@ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "license": "MIT", + "peer": true, "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", @@ -22265,6 +22398,7 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "license": "MIT", + "peer": true, "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -22405,6 +22539,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "license": "MIT", + "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -22588,6 +22723,7 @@ "resolved": "https://registry.npmjs.org/parse-imports-exports/-/parse-imports-exports-0.2.4.tgz", "integrity": "sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==", "license": "MIT", + "peer": true, "dependencies": { "parse-statements": "1.0.11" } @@ -22635,7 +22771,8 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/parse-statements/-/parse-statements-1.0.11.tgz", "integrity": "sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/parse-url": { "version": "9.2.0", @@ -23085,7 +23222,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -23223,6 +23359,7 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "license": "MIT", + "peer": true, "engines": { "node": ">= 0.8.0" } @@ -23248,6 +23385,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "license": "MIT", + "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -23262,6 +23400,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -23273,7 +23412,8 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/prismjs": { "version": "1.30.0", @@ -23378,6 +23518,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz", "integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-transform": "^1.0.0" } @@ -23387,6 +23528,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0" } @@ -23396,6 +23538,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz", "integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -23407,6 +23550,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz", "integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0", @@ -23418,6 +23562,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.0.tgz", "integrity": "sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-keymap": "^1.0.0", "prosemirror-model": "^1.0.0", @@ -23430,6 +23575,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.5.0.tgz", "integrity": "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.0.0", @@ -23442,6 +23588,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.1.tgz", "integrity": "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.0.0" @@ -23452,6 +23599,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz", "integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-state": "^1.0.0", "w3c-keyname": "^2.2.0" @@ -23473,6 +23621,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz", "integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==", "license": "MIT", + "peer": true, "dependencies": { "crelt": "^1.0.0", "prosemirror-commands": "^1.0.0", @@ -23485,7 +23634,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.4.tgz", "integrity": "sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==", "license": "MIT", - "peer": true, "dependencies": { "orderedmap": "^2.0.0" } @@ -23495,6 +23643,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz", "integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-model": "^1.25.0" } @@ -23504,6 +23653,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz", "integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", @@ -23515,7 +23665,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.4.tgz", "integrity": "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", @@ -23527,6 +23676,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.8.5.tgz", "integrity": "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==", "license": "MIT", + "peer": true, "dependencies": { "prosemirror-keymap": "^1.2.3", "prosemirror-model": "^1.25.4", @@ -23540,6 +23690,7 @@ "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", "license": "MIT", + "peer": true, "dependencies": { "@remirror/core-constants": "3.0.0", "escape-string-regexp": "^4.0.0" @@ -23555,6 +23706,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -23576,7 +23728,6 @@ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.41.6.tgz", "integrity": "sha512-mxpcDG4hNQa/CPtzxjdlir5bJFDlm0/x5nGBbStB2BWX+XOQ9M8ekEG+ojqB5BcVu2Rc80/jssCMZzSstJuSYg==", "license": "MIT", - "peer": true, "dependencies": { "prosemirror-model": "^1.20.0", "prosemirror-state": "^1.0.0", @@ -23654,7 +23805,8 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true, "license": "MIT", - "optional": true + "optional": true, + "peer": true }, "node_modules/pump": { "version": "3.0.3", @@ -23831,7 +23983,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -23841,7 +23992,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -24218,6 +24368,7 @@ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } @@ -24353,6 +24504,7 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.2.tgz", "integrity": "sha512-035InabNu/c1lW0tzPhAgapKctblppqsKKG9ZaNzbr+gXwWMjXoiyGSyB9sArzrjG7jY+zntRq5ZSUYemrnWVQ==", "license": "BlueOak-1.0.0", + "peer": true, "dependencies": { "minimatch": "^10.1.2", "minipass": "^7.1.2", @@ -24370,6 +24522,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.2.tgz", "integrity": "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw==", "license": "BlueOak-1.0.0", + "peer": true, "dependencies": { "@isaacs/brace-expansion": "^5.0.1" }, @@ -24396,7 +24549,6 @@ "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -24498,7 +24650,8 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/run-applescript": { "version": "7.1.0", @@ -24550,7 +24703,6 @@ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -24640,7 +24792,6 @@ "integrity": "sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -24755,6 +24906,7 @@ "resolved": "https://registry.npmjs.org/sdbm/-/sdbm-3.0.0.tgz", "integrity": "sha512-9FHNk9qJKuRxkUeQQdRp8WLCFaL4hvPtYz/2xNAOkuZzQ3ZqMMkZ1CrkKPDA4lxbenMml0JRKHGyTyucK/JBBg==", "license": "MIT", + "peer": true, "engines": { "node": ">=20" }, @@ -25447,6 +25599,7 @@ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "license": "MIT", + "peer": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -25530,6 +25683,7 @@ "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=12.0.0" } @@ -25562,7 +25716,6 @@ "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.2.8.tgz", "integrity": "sha512-885uSIn8NQw2ZG7vy84K45lHCOSyz1DVsDV8pHiHQj3J0riCuWLNeO50lK9z98zE8kjhgTtxAAkMTy5nkmNRKQ==", "license": "MIT", - "peer": true, "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.1", @@ -25732,6 +25885,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz", "integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==", "license": "MIT", + "peer": true, "dependencies": { "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" @@ -25923,6 +26077,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "license": "MIT", + "peer": true, "engines": { "node": ">=4" } @@ -25954,6 +26109,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "license": "MIT", + "peer": true, "engines": { "node": ">=8" }, @@ -26200,6 +26356,7 @@ "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", "license": "MIT", + "peer": true, "dependencies": { "@pkgr/core": "^0.2.9" }, @@ -26221,6 +26378,7 @@ "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-4.1.1.tgz", "integrity": "sha512-iK5/YhZxq5GO5z8wb0bY1317uDF3Zjpha0QFFLA8/trAoiLbQD0HUbMesEaxyzUgDxi2QlcbM8IvqOlEjgoXBA==", "license": "MIT", + "peer": true, "dependencies": { "array-back": "^6.2.2", "wordwrapjs": "^5.1.0" @@ -26427,7 +26585,6 @@ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -26619,7 +26776,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -26751,6 +26907,7 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.12" }, @@ -26773,6 +26930,7 @@ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "license": "MIT", + "peer": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.2", @@ -26785,6 +26943,7 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "license": "MIT", + "peer": true, "dependencies": { "minimist": "^1.2.0" }, @@ -26796,8 +26955,7 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "peer": true + "license": "0BSD" }, "node_modules/tuf-js": { "version": "3.1.0", @@ -26921,6 +27079,7 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "license": "MIT", + "peer": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -26933,6 +27092,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.2.0.tgz", "integrity": "sha512-5zknd7Dss75pMSED270A1RQS3KloqRJA9XbXLe0eCxyw7xXFb3rd+9B0UQ/0E+LQT6lnrLviEolYORlRWamn4w==", "license": "(MIT OR CC0-1.0)", + "peer": true, "engines": { "node": ">=16" }, @@ -27057,7 +27217,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -27095,6 +27254,7 @@ "resolved": "https://registry.npmjs.org/typical/-/typical-7.3.0.tgz", "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", "license": "MIT", + "peer": true, "engines": { "node": ">=12.17" } @@ -27155,6 +27315,7 @@ "resolved": "https://registry.npmjs.org/undici/-/undici-7.21.0.tgz", "integrity": "sha512-Hn2tCQpoDt1wv23a68Ctc8Cr/BHpUSfaPYrkajTXOS9IKpxVRx/X5m1K2YkbK2ipgZgxXSgsUinl3x+2YdSSfg==", "license": "MIT", + "peer": true, "engines": { "node": ">=20.18.1" } @@ -27299,6 +27460,7 @@ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", "license": "MIT", + "peer": true, "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" @@ -27469,6 +27631,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -27478,6 +27641,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -27623,7 +27787,6 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -28300,7 +28463,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -28351,7 +28513,8 @@ "version": "2.2.8", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/watchpack": { "version": "2.4.2", @@ -28414,7 +28577,6 @@ "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -28492,7 +28654,6 @@ "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", @@ -28912,6 +29073,7 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -28921,6 +29083,7 @@ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-5.1.1.tgz", "integrity": "sha512-0yweIbkINJodk27gX9LBGMzyQdBDan3s/dEAiwBOj+Mf0PPyWL6/rikalkv8EeD0E8jm4o5RXEOrFTP3NXbhJg==", "license": "MIT", + "peer": true, "engines": { "node": ">=12.17" } @@ -29174,7 +29337,6 @@ "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", "dev": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, @@ -29289,7 +29451,6 @@ "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -29311,8 +29472,7 @@ "version": "0.15.1", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/zwitch": { "version": "2.0.4", diff --git a/packages/nimble-components/src/table-column/base/index.ts b/packages/nimble-components/src/table-column/base/index.ts index f60852b68a..853434ba67 100644 --- a/packages/nimble-components/src/table-column/base/index.ts +++ b/packages/nimble-components/src/table-column/base/index.ts @@ -36,6 +36,9 @@ export abstract class TableColumn< @attr({ attribute: 'column-hidden', mode: 'boolean' }) public columnHidden = false; + + @attr({ attribute: 'pinned', mode: 'boolean' }) + public pinned = false; /** @internal */ @observable diff --git a/packages/nimble-components/src/table/index.ts b/packages/nimble-components/src/table/index.ts index e75000ffa7..8734716fb0 100644 --- a/packages/nimble-components/src/table/index.ts +++ b/packages/nimble-components/src/table/index.ts @@ -249,6 +249,12 @@ export class Table< @observable public visibleColumns: TableColumn[] = []; + /** + * @internal + */ + @observable + public pinnedColumns: TableColumn[] = []; + /** * @internal * This value determines the size of the viewport area when a user has created horizontal scrollable @@ -699,8 +705,9 @@ export class Table< if (this.tableUpdateTracker.updateColumnWidths) { this.rowGridColumns = this.layoutManager.getGridTemplateColumns(); this.visibleColumns = this.columns.filter( - column => !column.columnHidden + column => !column.columnHidden && !column.pinned ); + this.pinnedColumns = this.columns.filter(column => column.pinned); } if (this.tableUpdateTracker.requiresKeyboardFocusReset) { diff --git a/packages/nimble-components/src/table/models/table-layout-manager.ts b/packages/nimble-components/src/table/models/table-layout-manager.ts index 6fa2161fa4..889a804d85 100644 --- a/packages/nimble-components/src/table/models/table-layout-manager.ts +++ b/packages/nimble-components/src/table/models/table-layout-manager.ts @@ -362,7 +362,7 @@ export class TableLayoutManager { } private getVisibleColumns(): TableColumn[] { - return this.table.columns.filter(column => !column.columnHidden); + return this.table.columns.filter(column => !column.columnHidden && !column.pinned); } private getLeftColumnIndexFromDivider(dividerIndex: number): number { diff --git a/packages/nimble-components/src/table/models/table-update-tracker.ts b/packages/nimble-components/src/table/models/table-update-tracker.ts index 39fb4c4c5e..d6183ddccf 100644 --- a/packages/nimble-components/src/table/models/table-update-tracker.ts +++ b/packages/nimble-components/src/table/models/table-update-tracker.ts @@ -29,7 +29,8 @@ const trackedItems = [ 'columnDefinition', 'actionMenuSlots', 'selectionMode', - 'actionMenusPreserveSelection' + 'actionMenusPreserveSelection', + 'columnPinned' ] as const; /** @@ -109,6 +110,7 @@ export class TableUpdateTracker< this.isTracked('columnSortDisabled') || this.isTracked('columnDefinition') || this.isTracked('columnHidden') + || this.isTracked('columnPinned') || this.isTracked('selectionMode') || this.isTracked('actionMenuSlots') ); @@ -160,6 +162,12 @@ export class TableUpdateTracker< } else if (isColumnProperty(changedColumnProperty, 'columnHidden')) { this.track('columnWidths'); this.track('columnHidden'); + }else if (isColumnProperty(changedColumnProperty, 'columnHidden')) { + this.track('columnWidths'); + this.track('columnHidden'); + } else if (isColumnProperty(changedColumnProperty, 'pinned')) { + this.track('columnWidths'); + this.track('columnPinned'); } else if (isColumnProperty(changedColumnProperty, 'actionMenuSlot')) { this.track('actionMenuSlots'); } else if ( diff --git a/packages/nimble-components/src/table/template.ts b/packages/nimble-components/src/table/template.ts index 6d13e8ba27..77c919b44c 100644 --- a/packages/nimble-components/src/table/template.ts +++ b/packages/nimble-components/src/table/template.ts @@ -52,6 +52,28 @@ export const template = html` ">
+ ${repeat(x => x.pinnedColumns, html` +
+ ${when((_, c) => c.index > 0, html` +
+ `)} + <${tableHeaderTag} + class="header" + ${'' /* tabindex managed dynamically by KeyboardNavigationManager (if column sorting not disabled) */} + sort-direction="${x => (typeof x.columnInternals.currentSortIndex === 'number' ? x.columnInternals.currentSortDirection : TableColumnSortDirection.none)}" + ?first-sorted-column="${(x, c) => x === c.parent.firstSortedColumn}" + ?indicators-hidden="${x => x.columnInternals.hideHeaderIndicators}" + @keydown="${(x, c) => c.parent.onHeaderKeyDown(x, c.event as KeyboardEvent)}" + @click="${(x, c) => c.parent.toggleColumnSort(x, (c.event as MouseEvent).shiftKey)}" + :alignment="${x => x.columnInternals.headerAlignment}" + > + + + ${when((_, c) => c.index < c.length - 1, html` +
+ `)} +
+ `, { positioning: true })} ${when(x => x.showRowOperationColumn, html
` From dbbb14fe3561f4f4d35fe697e2b045329df8e9e6 Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Wed, 4 Mar 2026 13:07:05 -0600 Subject: [PATCH 02/17] working? --- .../src/table/components/group-row/index.ts | 3 ++ .../src/table/components/group-row/styles.ts | 2 + .../table/components/group-row/template.ts | 7 +++- .../src/table/components/row/styles.ts | 5 +++ .../src/table/components/row/template.ts | 38 +++++++++++++++++- packages/nimble-components/src/table/index.ts | 40 +++++++++++++++++++ .../nimble-components/src/table/styles.ts | 5 +++ .../nimble-components/src/table/template.ts | 16 +++----- .../mapping/table-column-mapping.stories.ts | 14 ++++++- .../src/nimble/table/table.stories.ts | 1 + 10 files changed, 118 insertions(+), 13 deletions(-) diff --git a/packages/nimble-components/src/table/components/group-row/index.ts b/packages/nimble-components/src/table/components/group-row/index.ts index 4d9eefab43..c9362fd922 100644 --- a/packages/nimble-components/src/table/components/group-row/index.ts +++ b/packages/nimble-components/src/table/components/group-row/index.ts @@ -27,6 +27,9 @@ export class TableGroupRow extends FoundationElement { @observable public nestingLevel = 0; + @observable + public pinnedColumnOffset = 0; + /** * Row index in the flattened set of all regular and group header rows. * Represents the index in table.tableData (TableRowState[]). diff --git a/packages/nimble-components/src/table/components/group-row/styles.ts b/packages/nimble-components/src/table/components/group-row/styles.ts index 00b4015959..4c6eeb1fa4 100644 --- a/packages/nimble-components/src/table/components/group-row/styles.ts +++ b/packages/nimble-components/src/table/components/group-row/styles.ts @@ -26,6 +26,7 @@ export const styles = css` height: calc(${controlHeight} + 2 * ${borderWidth}); border-top: calc(2 * ${borderWidth}) solid ${applicationBackgroundColor}; grid-template-columns: + calc(var(--ni-private-table-group-row-pinned-column-offset)) calc( ${controlHeight} * (var(--ni-private-table-group-row-indent-level) + 1) @@ -35,6 +36,7 @@ export const styles = css` :host([selectable]) { grid-template-columns: + calc(var(--ni-private-table-group-row-pinned-column-offset)) ${controlHeight} calc( ${controlHeight} * diff --git a/packages/nimble-components/src/table/components/group-row/template.ts b/packages/nimble-components/src/table/components/group-row/template.ts index cf053c6a6e..322d713177 100644 --- a/packages/nimble-components/src/table/components/group-row/template.ts +++ b/packages/nimble-components/src/table/components/group-row/template.ts @@ -15,8 +15,13 @@ export const template = html` role="row" @click=${x => x.onGroupExpandToggle()} aria-expanded=${x => x.expanded} - style="--ni-private-table-group-row-indent-level: ${x => x.nestingLevel};" + style=" + --ni-private-table-group-row-indent-level: ${x => x.nestingLevel}; + --ni-private-table-group-row-pinned-column-offset: ${x => x.pinnedColumnOffset}px; + " > + + ${when(x => x.selectable, html` <${checkboxTag} diff --git a/packages/nimble-components/src/table/components/row/styles.ts b/packages/nimble-components/src/table/components/row/styles.ts index e477f17964..d492027fb2 100644 --- a/packages/nimble-components/src/table/components/row/styles.ts +++ b/packages/nimble-components/src/table/components/row/styles.ts @@ -115,6 +115,11 @@ export const styles = css` width: ${mediumPadding}; } + .pinned-cell-container { + display: grid; + grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns); + } + .cell-container { display: grid; width: 100%; diff --git a/packages/nimble-components/src/table/components/row/template.ts b/packages/nimble-components/src/table/components/row/template.ts index f7260d5c6e..9108b8fe73 100644 --- a/packages/nimble-components/src/table/components/row/template.ts +++ b/packages/nimble-components/src/table/components/row/template.ts @@ -27,6 +27,42 @@ export const template = html` aria-expanded=${x => x.expanded} style="--ni-private-table-row-indent-level: ${x => x.nestingLevel};" > + + ${repeat(x => x.columns, html` + ${when(x => x.pinned, html` + <${tableCellTag} + class="cell" + :cellState="${(_, c) => c.parent.cellStates[c.index]}" + :cellViewTemplate="${x => x.columnInternals.cellViewTemplate}" + :column="${x => x}" + column-id="${x => x.columnId}" + :recordId="${(_, c) => c.parent.recordId}" + ?has-action-menu="${x => !!x.actionMenuSlot}" + action-menu-label="${x => x.actionMenuLabel}" + @cell-action-menu-beforetoggle="${(x, c) => c.parent.onCellActionMenuBeforeToggle(c.event as CustomEvent, x)}" + @cell-action-menu-toggle="${(x, c) => c.parent.onCellActionMenuToggle(c.event as CustomEvent, x)}" + @cell-view-slots-request="${(x, c) => c.parent.onCellViewSlotsRequest(x, c.event as CustomEvent)}" + :nestingLevel="${(_, c) => c.parent.cellIndentLevels[c.index]}" + > + + ${when((x, c) => ((c.parent as TableRow).currentActionMenuColumn === x) && x.actionMenuSlot, html` + + `)} + + ${repeat(x => x.columnInternals.slotNames, html` + + `)} + + `)} + `, { recycle: false, positioning: true })} + + ${when(x => !x.rowOperationGridCellHidden, html` ${when(x => x.showSelectionCheckbox, html` @@ -75,7 +111,7 @@ export const template = html` class="cell-container ${x => (x.isNestedParent ? 'nested-parent' : '')}" > ${repeat(x => x.columns, html` - ${when(x => !x.columnHidden, html` + ${when(x => !x.columnHidden && !x.pinned, html` <${tableCellTag} class="cell" :cellState="${(_, c) => c.parent.cellStates[c.index]}" diff --git a/packages/nimble-components/src/table/index.ts b/packages/nimble-components/src/table/index.ts index 8734716fb0..d33bfea924 100644 --- a/packages/nimble-components/src/table/index.ts +++ b/packages/nimble-components/src/table/index.ts @@ -207,6 +207,46 @@ export class Table< return ''; } + /** + * @internal + */ + @volatile + public get pinnedColumnOffset(): number { + let offset = 0; + for (const column of this.pinnedColumns) { + if (column.columnInternals.currentPixelWidth) { + const coercedPixelWidth = Math.max( + column.columnInternals.minPixelWidth, + column.columnInternals.currentPixelWidth + ); + offset += coercedPixelWidth; + } + } + return offset; + } + + /** + * @internal + */ + @volatile + public get pinnedColumnsGridTemplateColumns(): string { + return this.pinnedColumns.map(column => { + const { + minPixelWidth, + currentPixelWidth + } = column.columnInternals; + if (currentPixelWidth !== undefined) { + const coercedPixelWidth = Math.max( + minPixelWidth, + currentPixelWidth + ); + return `${coercedPixelWidth}px`; + } + }) + .join(' '); + + } + /** * @internal */ diff --git a/packages/nimble-components/src/table/styles.ts b/packages/nimble-components/src/table/styles.ts index 5c56f19acb..e465f67a2a 100644 --- a/packages/nimble-components/src/table/styles.ts +++ b/packages/nimble-components/src/table/styles.ts @@ -121,6 +121,11 @@ export const styles = css` visibility: visible; } + .pinned-columns-header-container { + display: grid; + grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns); + } + .header-container { display: flex; align-items: center; diff --git a/packages/nimble-components/src/table/template.ts b/packages/nimble-components/src/table/template.ts index 77c919b44c..2724e96f81 100644 --- a/packages/nimble-components/src/table/template.ts +++ b/packages/nimble-components/src/table/template.ts @@ -49,14 +49,12 @@ export const template = html
` --ni-private-table-row-grid-columns: ${x => (x.rowGridColumns ? x.rowGridColumns : '')}; --ni-private-table-cursor-override: ${x => (x.layoutManager.isColumnBeingSized ? 'col-resize' : 'default')}; --ni-private-table-scrollable-min-width: ${x => x.tableScrollableMinWidth}px; + --ni-private-table-pinned-columns-row-grid-columns: ${x => x.pinnedColumnsGridTemplateColumns}; ">
- ${repeat(x => x.pinnedColumns, html` -
- ${when((_, c) => c.index > 0, html` -
- `)} +
+ ${repeat(x => x.pinnedColumns, html` <${tableHeaderTag} class="header" ${'' /* tabindex managed dynamically by KeyboardNavigationManager (if column sorting not disabled) */} @@ -69,11 +67,8 @@ export const template = html
` > - ${when((_, c) => c.index < c.length - 1, html` -
- `)} - - `, { positioning: true })} + `, { positioning: true })} + ${when(x => x.showRowOperationColumn, html
` @@ -170,6 +165,7 @@ export const template = html
` :groupRowValue="${(x, c) => c.parent.tableData[x.index]?.groupRowValue}" ?expanded="${(x, c) => c.parent.tableData[x.index]?.isExpanded}" :nestingLevel="${(x, c) => c.parent.tableData[x.index]?.nestingLevel}" + :pinnedColumnOffset="${(_, c) => c.parent.pinnedColumnOffset}" :immediateChildCount="${(x, c) => c.parent.tableData[x.index]?.immediateChildCount}" :groupColumn="${(x, c) => c.parent.tableData[x.index]?.groupColumn}" ?selectable="${(_, c) => c.parent.selectionMode === TableRowSelectionMode.multiple}" diff --git a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts index f2c3b517dd..5885dbdf1a 100644 --- a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts +++ b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts @@ -26,6 +26,7 @@ import { const simpleData = [ { + id: '1', firstName: 'Ralph', lastName: 'Wiggum', status: 'fail', @@ -33,6 +34,7 @@ const simpleData = [ gender: 'male' }, { + id: '2', firstName: 'Marge', lastName: 'Simpson', status: 'success', @@ -40,6 +42,7 @@ const simpleData = [ gender: 'female' }, { + id: '3', firstName: 'Homer', lastName: 'Simpson', status: 'calculating', @@ -47,6 +50,7 @@ const simpleData = [ gender: 'male' }, { + id: '4', firstName: 'Bart', lastName: 'Simpson', status: 'success', @@ -54,6 +58,7 @@ const simpleData = [ gender: 'male' }, { + id: '5', firstName: 'Abbey', lastName: '?', status: 'unknown', @@ -89,6 +94,7 @@ export const mappingColumn: StoryObj = { ${ref('tableRef')} data-unused="${x => x.updateData(x)}" style="${isChromatic() ? '--ni-private-spinner-animation-play-state:paused' : ''}" + id-field-name="id" > <${tableColumnTextTag} field-name="firstName" > Name @@ -100,12 +106,18 @@ export const mappingColumn: StoryObj = { <${mappingSpinnerTag} key="calculating" text="Calculating" text-hidden> <${mappingEmptyTag} key="unknown" text="Unknown"> - <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}"> + <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" pinned> <${iconChartDiagramChildFocusTag} title="Is child"> <${mappingIconTag} key="false" icon="${iconXmarkTag}" severity="error" text="Not a child" text-hidden> <${mappingIconTag} key="true" icon="${iconCheckTag}" severity="success" text="Is a child" text-hidden> + <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" pinned> + <${iconXmarkTag} title="Is child"> + + <${mappingIconTag} key="false" icon="${iconXmarkTag}" severity="error" text="Not a child" text-hidden> + <${mappingIconTag} key="true" icon="${iconCheckTag}" severity="success" text="Is a child" text-hidden> + <${tableColumnMappingTag} field-name="gender" key-type="string"> Gender <${mappingTextTag} key="male" text="Male"> diff --git a/packages/storybook/src/nimble/table/table.stories.ts b/packages/storybook/src/nimble/table/table.stories.ts index f3575e38a0..e63afab34a 100644 --- a/packages/storybook/src/nimble/table/table.stories.ts +++ b/packages/storybook/src/nimble/table/table.stories.ts @@ -292,6 +292,7 @@ export const table: StoryObj = { column-id="first-name-column" field-name="firstName" action-menu-slot="name-menu" action-menu-label="Configure name" + pinned > <${iconUserTag} title="First Name"> From 385d887643799e8a8b2cfbd8fcfedf46ba3eb889 Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:48:07 -0600 Subject: [PATCH 03/17] a few improvements --- .../src/table/components/row/template.ts | 2 +- packages/nimble-components/src/table/index.ts | 3 ++- .../src/table/models/table-validator.ts | 14 +++++++++++++- packages/nimble-components/src/table/types.ts | 1 + 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/nimble-components/src/table/components/row/template.ts b/packages/nimble-components/src/table/components/row/template.ts index 9108b8fe73..af0f643281 100644 --- a/packages/nimble-components/src/table/components/row/template.ts +++ b/packages/nimble-components/src/table/components/row/template.ts @@ -29,7 +29,7 @@ export const template = html` > ${repeat(x => x.columns, html` - ${when(x => x.pinned, html` + ${when(x => !x.columnHidden && x.pinned, html` <${tableCellTag} class="cell" :cellState="${(_, c) => c.parent.cellStates[c.index]}" diff --git a/packages/nimble-components/src/table/index.ts b/packages/nimble-components/src/table/index.ts index d33bfea924..c53836732c 100644 --- a/packages/nimble-components/src/table/index.ts +++ b/packages/nimble-components/src/table/index.ts @@ -747,7 +747,7 @@ export class Table< this.visibleColumns = this.columns.filter( column => !column.columnHidden && !column.pinned ); - this.pinnedColumns = this.columns.filter(column => column.pinned); + this.pinnedColumns = this.columns.filter(column => column.pinned && !column.columnHidden); } if (this.tableUpdateTracker.requiresKeyboardFocusReset) { @@ -1135,6 +1135,7 @@ export class Table< ) ); this.tableValidator.validateColumnConfigurations(this.columns); + this.tableValidator.validatePinnedColumnConfigurations(this.columns); if (this.dataHierarchyManager) { this.validateWithData(this.dataHierarchyManager.getAllRecords()); } diff --git a/packages/nimble-components/src/table/models/table-validator.ts b/packages/nimble-components/src/table/models/table-validator.ts index 2a2dbf563a..fbc8a4de6e 100644 --- a/packages/nimble-components/src/table/models/table-validator.ts +++ b/packages/nimble-components/src/table/models/table-validator.ts @@ -21,6 +21,7 @@ export class TableValidator { private idFieldNameNotConfigured = false; private invalidColumnConfiguration = false; private invalidParentIdConfiguration = false; + private invalidPinnedColumnConfiguration = false; private readonly recordIds = new Set(); @@ -35,7 +36,8 @@ export class TableValidator { duplicateGroupIndex: this.duplicateGroupIndex, idFieldNameNotConfigured: this.idFieldNameNotConfigured, invalidColumnConfiguration: this.invalidColumnConfiguration, - invalidParentIdConfiguration: this.invalidParentIdConfiguration + invalidParentIdConfiguration: this.invalidParentIdConfiguration, + invalidPinnedColumnConfiguration: this.invalidPinnedColumnConfiguration }; } @@ -152,9 +154,19 @@ export class TableValidator { this.invalidColumnConfiguration = columns.some( x => !x.columnInternals.validator.isColumnValid ); + return !this.invalidColumnConfiguration; } + public validatePinnedColumnConfigurations( + columns: readonly TableColumn[] + ): boolean { + this.invalidPinnedColumnConfiguration = columns.some( + x => x.pinned && x.columnInternals.currentPixelWidth === undefined + ); + return !this.invalidPinnedColumnConfiguration; + } + public getPresentRecordIds( requestedRecordIds: readonly string[] ): string[] { diff --git a/packages/nimble-components/src/table/types.ts b/packages/nimble-components/src/table/types.ts index ac2c4cf393..13b4ca7f4d 100644 --- a/packages/nimble-components/src/table/types.ts +++ b/packages/nimble-components/src/table/types.ts @@ -79,6 +79,7 @@ export interface TableValidity extends ValidityObject { readonly idFieldNameNotConfigured: boolean; readonly invalidColumnConfiguration: boolean; readonly invalidParentIdConfiguration: boolean; + readonly invalidPinnedColumnConfiguration: boolean; } /** From 854200c6b8d902357bba17d178b01ca501ccc892 Mon Sep 17 00:00:00 2001 From: mollykreis <20542556+mollykreis@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:46:54 -0600 Subject: [PATCH 04/17] mostly working -- styling needs help --- .../src/table/components/group-row/styles.ts | 27 ++++++++++++++++++- .../table/components/group-row/template.ts | 2 +- .../src/table/components/row/styles.ts | 18 +++++++++++++ .../src/table/components/row/template.ts | 2 +- .../nimble-components/src/table/styles.ts | 8 ++++++ .../nimble-components/src/table/template.ts | 1 + 6 files changed, 55 insertions(+), 3 deletions(-) diff --git a/packages/nimble-components/src/table/components/group-row/styles.ts b/packages/nimble-components/src/table/components/group-row/styles.ts index 4c6eeb1fa4..fb4b39ba35 100644 --- a/packages/nimble-components/src/table/components/group-row/styles.ts +++ b/packages/nimble-components/src/table/components/group-row/styles.ts @@ -8,7 +8,8 @@ import { controlHeight, fillHoverColor, mediumPadding, - standardPadding + standardPadding, + tableRowBorderColor } from '../../../theme-provider/design-tokens'; import { Theme } from '../../../theme-provider/types'; import { hexToRgbaCssColor } from '../../../utilities/style/colors'; @@ -16,6 +17,7 @@ import { themeBehavior } from '../../../utilities/style/theme'; import { userSelectNone } from '../../../utilities/style/user-select'; import { styles as expandCollapseStyles } from '../../../patterns/expand-collapse/styles'; import { focusVisible } from '../../../utilities/style/focus'; +import { ZIndexLevels } from '../../../utilities/style/types'; export const styles = css` ${display('grid')} @@ -63,6 +65,25 @@ export const styles = css` outline-offset: calc(-2 * ${borderWidth}); } + .pinned-column-spacer { + position: sticky; + left: 0; + background: ${tableRowBorderColor}; + z-index: ${ZIndexLevels.zIndex1000}; + height: 100%; + } + + .expand-collapse-button-container { + position: sticky; + background: ${tableRowBorderColor}; + left: var(--ni-private-table-pinned-column-offset); + z-index: ${ZIndexLevels.zIndex1000}; + } + + .expand-collapse-button-container.selectable { + left: calc(var(--ni-private-table-pinned-column-offset) + 32px); + } + .expand-collapse-button { margin-left: calc( ${mediumPadding} + ${standardPadding} * 2 * @@ -90,6 +111,10 @@ export const styles = css` .checkbox-container { display: flex; + position: sticky; + left: var(--ni-private-table-pinned-column-offset); + z-index: ${ZIndexLevels.zIndex1000}; + background: ${tableRowBorderColor}; } .selection-checkbox { diff --git a/packages/nimble-components/src/table/components/group-row/template.ts b/packages/nimble-components/src/table/components/group-row/template.ts index 322d713177..2985242b67 100644 --- a/packages/nimble-components/src/table/components/group-row/template.ts +++ b/packages/nimble-components/src/table/components/group-row/template.ts @@ -36,7 +36,7 @@ export const template = html` `)} - + <${buttonTag} appearance="${ButtonAppearance.ghost}" content-hidden diff --git a/packages/nimble-components/src/table/components/row/styles.ts b/packages/nimble-components/src/table/components/row/styles.ts index d492027fb2..4623600b08 100644 --- a/packages/nimble-components/src/table/components/row/styles.ts +++ b/packages/nimble-components/src/table/components/row/styles.ts @@ -19,6 +19,7 @@ import { hexToRgbaCssColor } from '../../../utilities/style/colors'; import { themeBehavior } from '../../../utilities/style/theme'; import { styles as expandCollapseStyles } from '../../../patterns/expand-collapse/styles'; import { focusVisible } from '../../../utilities/style/focus'; +import { ZIndexLevels } from '../../../utilities/style/types'; export const styles = css` ${display('flex')} @@ -96,6 +97,10 @@ export const styles = css` .row-operations-container { flex: 0 0 auto; display: flex; + position: sticky; + z-index: ${ZIndexLevels.zIndex1000}; + background: ${applicationBackgroundColor}; + left: var(--ni-private-table-pinned-column-offset); } .selection-checkbox { @@ -109,15 +114,28 @@ export const styles = css` .row-front-spacer { width: ${controlHeight}; flex: 0 0 auto; + background: ${applicationBackgroundColor}; + position: sticky; + left: var(--ni-private-table-pinned-column-offset); + z-index: ${ZIndexLevels.zIndex1000}; } .row-front-spacer.reduced-size-spacer { width: ${mediumPadding}; } + .row-front-spacer.selectable { + left: calc(var(--ni-private-table-pinned-column-offset) + 32px); + } + .pinned-cell-container { display: grid; grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns); + + position: sticky; + left: 0; + background: ${applicationBackgroundColor}; + z-index: ${ZIndexLevels.zIndex1000}; } .cell-container { diff --git a/packages/nimble-components/src/table/components/row/template.ts b/packages/nimble-components/src/table/components/row/template.ts index af0f643281..ffa2027e8b 100644 --- a/packages/nimble-components/src/table/components/row/template.ts +++ b/packages/nimble-components/src/table/components/row/template.ts @@ -80,7 +80,7 @@ export const template = html` `)} `)} - + ${when(x => x.isParentRow, html` ${when(x => x.loading, html` diff --git a/packages/nimble-components/src/table/styles.ts b/packages/nimble-components/src/table/styles.ts index e465f67a2a..225bdff938 100644 --- a/packages/nimble-components/src/table/styles.ts +++ b/packages/nimble-components/src/table/styles.ts @@ -90,6 +90,10 @@ export const styles = css` .header-row-action-container { display: flex; align-items: center; + position: sticky; + background: ${applicationBackgroundColor}; + left: var(--ni-private-table-pinned-column-offset); + z-index: ${ZIndexLevels.zIndex1000}; } .checkbox-container { @@ -124,6 +128,10 @@ export const styles = css` .pinned-columns-header-container { display: grid; grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns); + position: sticky; + left: 0; + z-index: ${ZIndexLevels.zIndex1000}; + background: ${applicationBackgroundColor}; } .header-container { diff --git a/packages/nimble-components/src/table/template.ts b/packages/nimble-components/src/table/template.ts index 2724e96f81..4cbac49628 100644 --- a/packages/nimble-components/src/table/template.ts +++ b/packages/nimble-components/src/table/template.ts @@ -50,6 +50,7 @@ export const template = html
` --ni-private-table-cursor-override: ${x => (x.layoutManager.isColumnBeingSized ? 'col-resize' : 'default')}; --ni-private-table-scrollable-min-width: ${x => x.tableScrollableMinWidth}px; --ni-private-table-pinned-columns-row-grid-columns: ${x => x.pinnedColumnsGridTemplateColumns}; + --ni-private-table-pinned-column-offset: ${x => x.pinnedColumnOffset}px; ">
From 1b998696e283dfba7db3e3d48ddb9974ff1f614a Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 21 May 2026 11:50:10 -0500 Subject: [PATCH 05/17] only make the pinned column sticky --- .../src/table/components/group-row/styles.ts | 8 ----- .../src/table/components/row/styles.ts | 13 -------- packages/nimble-components/src/table/index.ts | 31 ++++++++++++++----- .../src/table/models/table-update-tracker.ts | 3 -- .../nimble-components/src/table/styles.ts | 4 --- .../nimble-components/src/table/template.ts | 1 - .../mapping/table-column-mapping.stories.ts | 15 ++------- .../src/nimble/table/table.stories.ts | 1 - 8 files changed, 27 insertions(+), 49 deletions(-) diff --git a/packages/nimble-components/src/table/components/group-row/styles.ts b/packages/nimble-components/src/table/components/group-row/styles.ts index fb4b39ba35..c59382e913 100644 --- a/packages/nimble-components/src/table/components/group-row/styles.ts +++ b/packages/nimble-components/src/table/components/group-row/styles.ts @@ -74,14 +74,10 @@ export const styles = css` } .expand-collapse-button-container { - position: sticky; background: ${tableRowBorderColor}; - left: var(--ni-private-table-pinned-column-offset); - z-index: ${ZIndexLevels.zIndex1000}; } .expand-collapse-button-container.selectable { - left: calc(var(--ni-private-table-pinned-column-offset) + 32px); } .expand-collapse-button { @@ -111,10 +107,6 @@ export const styles = css` .checkbox-container { display: flex; - position: sticky; - left: var(--ni-private-table-pinned-column-offset); - z-index: ${ZIndexLevels.zIndex1000}; - background: ${tableRowBorderColor}; } .selection-checkbox { diff --git a/packages/nimble-components/src/table/components/row/styles.ts b/packages/nimble-components/src/table/components/row/styles.ts index 4623600b08..031bb942aa 100644 --- a/packages/nimble-components/src/table/components/row/styles.ts +++ b/packages/nimble-components/src/table/components/row/styles.ts @@ -97,10 +97,6 @@ export const styles = css` .row-operations-container { flex: 0 0 auto; display: flex; - position: sticky; - z-index: ${ZIndexLevels.zIndex1000}; - background: ${applicationBackgroundColor}; - left: var(--ni-private-table-pinned-column-offset); } .selection-checkbox { @@ -114,24 +110,15 @@ export const styles = css` .row-front-spacer { width: ${controlHeight}; flex: 0 0 auto; - background: ${applicationBackgroundColor}; - position: sticky; - left: var(--ni-private-table-pinned-column-offset); - z-index: ${ZIndexLevels.zIndex1000}; } .row-front-spacer.reduced-size-spacer { width: ${mediumPadding}; } - .row-front-spacer.selectable { - left: calc(var(--ni-private-table-pinned-column-offset) + 32px); - } - .pinned-cell-container { display: grid; grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns); - position: sticky; left: 0; background: ${applicationBackgroundColor}; diff --git a/packages/nimble-components/src/table/index.ts b/packages/nimble-components/src/table/index.ts index c53836732c..d4bce51194 100644 --- a/packages/nimble-components/src/table/index.ts +++ b/packages/nimble-components/src/table/index.ts @@ -214,10 +214,13 @@ export class Table< public get pinnedColumnOffset(): number { let offset = 0; for (const column of this.pinnedColumns) { - if (column.columnInternals.currentPixelWidth) { + const resolvedPixelWidth = this.getPinnedColumnResolvedPixelWidth( + column + ); + if (resolvedPixelWidth !== undefined) { const coercedPixelWidth = Math.max( column.columnInternals.minPixelWidth, - column.columnInternals.currentPixelWidth + resolvedPixelWidth ); offset += coercedPixelWidth; } @@ -232,13 +235,15 @@ export class Table< public get pinnedColumnsGridTemplateColumns(): string { return this.pinnedColumns.map(column => { const { - minPixelWidth, - currentPixelWidth + minPixelWidth } = column.columnInternals; - if (currentPixelWidth !== undefined) { + const resolvedPixelWidth = this.getPinnedColumnResolvedPixelWidth( + column + ); + if (resolvedPixelWidth !== undefined) { const coercedPixelWidth = Math.max( minPixelWidth, - currentPixelWidth + resolvedPixelWidth ); return `${coercedPixelWidth}px`; } @@ -277,6 +282,16 @@ export class Table< */ public readonly keyboardNavigationManager: KeyboardNavigationManager; + private getPinnedColumnResolvedPixelWidth( + column: TableColumn + ): number | undefined { + const { + currentPixelWidth, + pixelWidth + } = column.columnInternals; + return currentPixelWidth ?? pixelWidth; + } + /** * @internal */ @@ -747,7 +762,9 @@ export class Table< this.visibleColumns = this.columns.filter( column => !column.columnHidden && !column.pinned ); - this.pinnedColumns = this.columns.filter(column => column.pinned && !column.columnHidden); + this.pinnedColumns = this.columns.filter( + column => column.pinned && !column.columnHidden + ); } if (this.tableUpdateTracker.requiresKeyboardFocusReset) { diff --git a/packages/nimble-components/src/table/models/table-update-tracker.ts b/packages/nimble-components/src/table/models/table-update-tracker.ts index d6183ddccf..1969255791 100644 --- a/packages/nimble-components/src/table/models/table-update-tracker.ts +++ b/packages/nimble-components/src/table/models/table-update-tracker.ts @@ -162,9 +162,6 @@ export class TableUpdateTracker< } else if (isColumnProperty(changedColumnProperty, 'columnHidden')) { this.track('columnWidths'); this.track('columnHidden'); - }else if (isColumnProperty(changedColumnProperty, 'columnHidden')) { - this.track('columnWidths'); - this.track('columnHidden'); } else if (isColumnProperty(changedColumnProperty, 'pinned')) { this.track('columnWidths'); this.track('columnPinned'); diff --git a/packages/nimble-components/src/table/styles.ts b/packages/nimble-components/src/table/styles.ts index 225bdff938..feb04f558e 100644 --- a/packages/nimble-components/src/table/styles.ts +++ b/packages/nimble-components/src/table/styles.ts @@ -90,10 +90,6 @@ export const styles = css` .header-row-action-container { display: flex; align-items: center; - position: sticky; - background: ${applicationBackgroundColor}; - left: var(--ni-private-table-pinned-column-offset); - z-index: ${ZIndexLevels.zIndex1000}; } .checkbox-container { diff --git a/packages/nimble-components/src/table/template.ts b/packages/nimble-components/src/table/template.ts index 4cbac49628..2724e96f81 100644 --- a/packages/nimble-components/src/table/template.ts +++ b/packages/nimble-components/src/table/template.ts @@ -50,7 +50,6 @@ export const template = html
` --ni-private-table-cursor-override: ${x => (x.layoutManager.isColumnBeingSized ? 'col-resize' : 'default')}; --ni-private-table-scrollable-min-width: ${x => x.tableScrollableMinWidth}px; --ni-private-table-pinned-columns-row-grid-columns: ${x => x.pinnedColumnsGridTemplateColumns}; - --ni-private-table-pinned-column-offset: ${x => x.pinnedColumnOffset}px; ">
diff --git a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts index 5885dbdf1a..1a023ff794 100644 --- a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts +++ b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts @@ -1,6 +1,7 @@ import { html, ref } from '@ni/fast-element'; import type { Meta, StoryObj } from '@storybook/html-vite'; import { tableTag } from '@ni/nimble-components/dist/esm/table'; +import { TableRowSelectionMode } from '@ni/nimble-components/dist/esm/table/types'; import { iconXmarkTag } from '@ni/nimble-components/dist/esm/icons/xmark'; import { tableColumnTextTag } from '@ni/nimble-components/dist/esm/table-column/text'; import { iconCheckTag } from '@ni/nimble-components/dist/esm/icons/check'; @@ -95,6 +96,7 @@ export const mappingColumn: StoryObj = { data-unused="${x => x.updateData(x)}" style="${isChromatic() ? '--ni-private-spinner-animation-play-state:paused' : ''}" id-field-name="id" + selection-mode="${x => TableRowSelectionMode[x.selectionMode]}" > <${tableColumnTextTag} field-name="firstName" > Name @@ -106,18 +108,12 @@ export const mappingColumn: StoryObj = { <${mappingSpinnerTag} key="calculating" text="Calculating" text-hidden> <${mappingEmptyTag} key="unknown" text="Unknown"> - <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" pinned> + <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" ?pinned="${x => x.widthMode === 'iconSize'}"> <${iconChartDiagramChildFocusTag} title="Is child"> <${mappingIconTag} key="false" icon="${iconXmarkTag}" severity="error" text="Not a child" text-hidden> <${mappingIconTag} key="true" icon="${iconCheckTag}" severity="success" text="Is a child" text-hidden> - <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" pinned> - <${iconXmarkTag} title="Is child"> - - <${mappingIconTag} key="false" icon="${iconXmarkTag}" severity="error" text="Not a child" text-hidden> - <${mappingIconTag} key="true" icon="${iconCheckTag}" severity="success" text="Is a child" text-hidden> - <${tableColumnMappingTag} field-name="gender" key-type="string"> Gender <${mappingTextTag} key="male" text="Male"> @@ -127,11 +123,6 @@ export const mappingColumn: StoryObj = { `), argTypes: { ...sharedTableArgTypes, - selectionMode: { - table: { - disable: true - } - }, fieldName: { name: 'field-name', description: diff --git a/packages/storybook/src/nimble/table/table.stories.ts b/packages/storybook/src/nimble/table/table.stories.ts index e63afab34a..f3575e38a0 100644 --- a/packages/storybook/src/nimble/table/table.stories.ts +++ b/packages/storybook/src/nimble/table/table.stories.ts @@ -292,7 +292,6 @@ export const table: StoryObj = { column-id="first-name-column" field-name="firstName" action-menu-slot="name-menu" action-menu-label="Configure name" - pinned > <${iconUserTag} title="First Name"> From 2d16e031788e1e7ea7d2848cc800decc285ae05d Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 14:38:03 -0500 Subject: [PATCH 06/17] apply cell indent levels to first non-pinned column --- packages/nimble-components/src/table/components/row/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nimble-components/src/table/components/row/index.ts b/packages/nimble-components/src/table/components/row/index.ts index 265e31fe1e..3ee24d603f 100644 --- a/packages/nimble-components/src/table/components/row/index.ts +++ b/packages/nimble-components/src/table/components/row/index.ts @@ -330,8 +330,9 @@ export class TableRow< } private updateCellIndentLevels(): void { + const firstNonPinnedIndex = this.columns.findIndex(col => !col.pinned); this.cellIndentLevels = this.columns.map((_, i) => { - return i === 0 ? this.nestingLevel : 0; + return i === firstNonPinnedIndex ? this.nestingLevel : 0; }); } From 355aa50c614051a934b65f5ef4de84745793e806 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 14:52:23 -0500 Subject: [PATCH 07/17] fix formatting issues --- .../src/table-column/base/index.ts | 2 +- packages/nimble-components/src/table/index.ts | 48 +++++++++---------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/packages/nimble-components/src/table-column/base/index.ts b/packages/nimble-components/src/table-column/base/index.ts index 853434ba67..ff56e88dce 100644 --- a/packages/nimble-components/src/table-column/base/index.ts +++ b/packages/nimble-components/src/table-column/base/index.ts @@ -36,7 +36,7 @@ export abstract class TableColumn< @attr({ attribute: 'column-hidden', mode: 'boolean' }) public columnHidden = false; - + @attr({ attribute: 'pinned', mode: 'boolean' }) public pinned = false; diff --git a/packages/nimble-components/src/table/index.ts b/packages/nimble-components/src/table/index.ts index d4bce51194..74a9fd412e 100644 --- a/packages/nimble-components/src/table/index.ts +++ b/packages/nimble-components/src/table/index.ts @@ -234,22 +234,22 @@ export class Table< @volatile public get pinnedColumnsGridTemplateColumns(): string { return this.pinnedColumns.map(column => { - const { - minPixelWidth - } = column.columnInternals; - const resolvedPixelWidth = this.getPinnedColumnResolvedPixelWidth( - column + const { + minPixelWidth + } = column.columnInternals; + const resolvedPixelWidth = this.getPinnedColumnResolvedPixelWidth( + column + ); + if (resolvedPixelWidth !== undefined) { + const coercedPixelWidth = Math.max( + minPixelWidth, + resolvedPixelWidth ); - if (resolvedPixelWidth !== undefined) { - const coercedPixelWidth = Math.max( - minPixelWidth, - resolvedPixelWidth - ); - return `${coercedPixelWidth}px`; - } - }) + return `${coercedPixelWidth}px`; + } + return ''; + }) .join(' '); - } /** @@ -282,16 +282,6 @@ export class Table< */ public readonly keyboardNavigationManager: KeyboardNavigationManager; - private getPinnedColumnResolvedPixelWidth( - column: TableColumn - ): number | undefined { - const { - currentPixelWidth, - pixelWidth - } = column.columnInternals; - return currentPixelWidth ?? pixelWidth; - } - /** * @internal */ @@ -885,6 +875,16 @@ export class Table< this.tableUpdateTracker.trackColumnInstancesChanged(); } + private getPinnedColumnResolvedPixelWidth( + column: TableColumn + ): number | undefined { + const { + currentPixelWidth, + pixelWidth + } = column.columnInternals; + return currentPixelWidth ?? pixelWidth; + } + private updateRequestedSlotsForOpeningActionMenu( openActionMenuRecordId: string ): void { From e2804b00239517d53bdcab6ff3a9444c0a348c89 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 15:44:58 -0500 Subject: [PATCH 08/17] cleanup styles and stoybook --- package-lock.json | 38 ++----------------- .../tests/nimble-table.directive.spec.ts | 5 ++- .../src/table/components/group-row/styles.ts | 1 - .../src/table/components/row/styles.ts | 1 - .../nimble-components/src/table/styles.ts | 1 - .../mapping/table-column-mapping.stories.ts | 22 ++++++----- 6 files changed, 20 insertions(+), 48 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3f519a82c..a79642052a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -224,7 +224,6 @@ "integrity": "sha512-diY415KLJZ6x1Kbwl9u96Jsz0OstE3asjXtJ9pmk1d+5gPuQ5jQyEsgC+WmEXzlec3iuVszm8AzNYYaqw6B+Zw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.35.0" }, @@ -238,7 +237,6 @@ "integrity": "sha512-uydqnSmpAjrgo8bqhE9N1wgcB98psTRRQXcjc4izwMB7yRl9C8uuAQ/5YqRj04U0mMQ+fdu2fcNF6m9+Z1BzDQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@algolia/client-common": "5.35.0" }, @@ -7188,7 +7186,6 @@ "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "@tybys/wasm-util": "^0.10.1" }, @@ -7245,6 +7242,7 @@ "resolved": "https://registry.npmjs.org/@ni/eslint-config-angular/-/eslint-config-angular-12.0.1.tgz", "integrity": "sha512-zf+60nhS8gobCHu+p8ST6u2KoGgu+MBIx4FDmOzehJb4YHoK0dpLSDi5JdMB7vf0ypknVcfcz+7kKMpvQjdELw==", "license": "MIT", + "peer": true, "peerDependencies": { "@ni/eslint-config-javascript": "^5.1.5", "@ni/eslint-config-typescript": "^5.0.6", @@ -7256,6 +7254,7 @@ "resolved": "https://registry.npmjs.org/@ni/eslint-config-javascript/-/eslint-config-javascript-5.1.5.tgz", "integrity": "sha512-QTiZUVexLaAUBNdq63ukvj8NSVYzVrD4rL9QTD+4Ze2+wQ4+wYaW/ryw5M2TDBjpHTmeA1vuZRqt4/Vl/LGbYg==", "license": "MIT", + "peer": true, "peerDependencies": { "@stylistic/eslint-plugin": "^5.10.0", "eslint": "^9.39.4", @@ -8298,7 +8297,6 @@ "hasInstallScript": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "detect-libc": "^2.0.3", "is-glob": "^4.0.3", @@ -8341,7 +8339,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8363,7 +8360,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8385,7 +8381,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8407,7 +8402,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8429,7 +8423,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8451,7 +8444,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8473,7 +8465,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8495,7 +8486,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8517,7 +8507,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8539,7 +8528,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8561,7 +8549,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8583,7 +8570,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8605,7 +8591,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">= 10.0.0" }, @@ -8620,8 +8605,7 @@ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/@parcel/watcher/node_modules/picomatch": { "version": "4.0.4", @@ -8630,7 +8614,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=12" }, @@ -10481,7 +10464,6 @@ "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", "license": "MIT", "optional": true, - "peer": true, "dependencies": { "tslib": "^2.4.0" } @@ -12123,7 +12105,6 @@ "resolved": "https://registry.npmjs.org/array-back/-/array-back-6.2.3.tgz", "integrity": "sha512-SGDvmg6QTYiTxCBkYVmThcoa67uLl35pyzRHdpCGBOcqFy6BtwnphoFPk7LhJshD+Yk1Kt35WGWeZPTgwR4Fhw==", "license": "MIT", - "peer": true, "engines": { "node": ">=12.17" } @@ -13481,7 +13462,6 @@ "integrity": "sha512-fytTsbndLbl+pPWtS0CxLV3BEWw9wJayB8NnU2cbQqVPsNdYezQeT+uIQv009m+GShnMNyuoBrRo8DTmuTfSCA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "array-back": "^6.1.2", "find-replace": "^3.0.0", @@ -13534,7 +13514,6 @@ "integrity": "sha512-pm0b+qv+CkWNriSTMsfnjChF9kH0kxz55y44Wo5le9qLxMj5xDQAaEd9ZN1ovSuk9CsrncWaFwgpOMg7ClJwkw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 12.0.0" } @@ -15013,7 +14992,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "prr": "~1.0.1" }, @@ -18288,7 +18266,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "bin": { "image-size": "bin/image-size.js" }, @@ -20522,7 +20499,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "bin": { "mime": "cli.js" }, @@ -20537,7 +20513,6 @@ "dev": true, "license": "BSD-3-Clause", "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -25485,7 +25460,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "iconv-lite": "^0.6.3", "sax": "^1.2.4" @@ -25504,7 +25478,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -27956,8 +27929,7 @@ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true }, "node_modules/pump": { "version": "3.0.4", @@ -30854,7 +30826,6 @@ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "license": "MIT", - "peer": true, "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -32923,7 +32894,6 @@ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } diff --git a/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts b/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts index ffd8d77d4b..8d7af13048 100644 --- a/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts +++ b/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts @@ -161,7 +161,8 @@ describe('Nimble table', () => { duplicateGroupIndex: false, idFieldNameNotConfigured: false, invalidColumnConfiguration: false, - invalidParentIdConfiguration: false + invalidParentIdConfiguration: false, + invalidPinnedColumnConfiguration: false }; expect(directive.validity).toEqual(expectedValidity); expect(nativeElement.validity).toEqual(expectedValidity); @@ -301,8 +302,8 @@ describe('Nimble table', () => { fixture.detectChanges(); expect(directive.parentIdFieldName).toEqual('parentField2'); - expect(nativeElement.parentIdFieldName).toEqual('parentField2'); }); + invalidPinnedColumnConfiguration: false it('can be configured with property binding for selectionMode', () => { expect(directive.selectionMode).toEqual(fixture.componentInstance.selectionMode); diff --git a/packages/nimble-components/src/table/components/group-row/styles.ts b/packages/nimble-components/src/table/components/group-row/styles.ts index c59382e913..2fa2bf8d92 100644 --- a/packages/nimble-components/src/table/components/group-row/styles.ts +++ b/packages/nimble-components/src/table/components/group-row/styles.ts @@ -69,7 +69,6 @@ export const styles = css` position: sticky; left: 0; background: ${tableRowBorderColor}; - z-index: ${ZIndexLevels.zIndex1000}; height: 100%; } diff --git a/packages/nimble-components/src/table/components/row/styles.ts b/packages/nimble-components/src/table/components/row/styles.ts index 031bb942aa..95c781efcf 100644 --- a/packages/nimble-components/src/table/components/row/styles.ts +++ b/packages/nimble-components/src/table/components/row/styles.ts @@ -122,7 +122,6 @@ export const styles = css` position: sticky; left: 0; background: ${applicationBackgroundColor}; - z-index: ${ZIndexLevels.zIndex1000}; } .cell-container { diff --git a/packages/nimble-components/src/table/styles.ts b/packages/nimble-components/src/table/styles.ts index feb04f558e..ed60699a6e 100644 --- a/packages/nimble-components/src/table/styles.ts +++ b/packages/nimble-components/src/table/styles.ts @@ -126,7 +126,6 @@ export const styles = css` grid-template-columns: var(--ni-private-table-pinned-columns-row-grid-columns); position: sticky; left: 0; - z-index: ${ZIndexLevels.zIndex1000}; background: ${applicationBackgroundColor}; } diff --git a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts index 1a023ff794..89f7b9d6bc 100644 --- a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts +++ b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts @@ -1,7 +1,6 @@ import { html, ref } from '@ni/fast-element'; import type { Meta, StoryObj } from '@storybook/html-vite'; import { tableTag } from '@ni/nimble-components/dist/esm/table'; -import { TableRowSelectionMode } from '@ni/nimble-components/dist/esm/table/types'; import { iconXmarkTag } from '@ni/nimble-components/dist/esm/icons/xmark'; import { tableColumnTextTag } from '@ni/nimble-components/dist/esm/table-column/text'; import { iconCheckTag } from '@ni/nimble-components/dist/esm/icons/check'; @@ -27,7 +26,6 @@ import { const simpleData = [ { - id: '1', firstName: 'Ralph', lastName: 'Wiggum', status: 'fail', @@ -35,7 +33,6 @@ const simpleData = [ gender: 'male' }, { - id: '2', firstName: 'Marge', lastName: 'Simpson', status: 'success', @@ -43,7 +40,6 @@ const simpleData = [ gender: 'female' }, { - id: '3', firstName: 'Homer', lastName: 'Simpson', status: 'calculating', @@ -51,7 +47,6 @@ const simpleData = [ gender: 'male' }, { - id: '4', firstName: 'Bart', lastName: 'Simpson', status: 'success', @@ -59,7 +54,6 @@ const simpleData = [ gender: 'male' }, { - id: '5', firstName: 'Abbey', lastName: '?', status: 'unknown', @@ -79,6 +73,7 @@ interface MappingColumnTableArgs extends SharedTableArgs { fieldName: string; keyType: string; widthMode: keyof typeof TableColumnMappingWidthMode; + pinned: boolean; checkValidity: () => void; validity: () => void; content: undefined; @@ -95,8 +90,6 @@ export const mappingColumn: StoryObj = { ${ref('tableRef')} data-unused="${x => x.updateData(x)}" style="${isChromatic() ? '--ni-private-spinner-animation-play-state:paused' : ''}" - id-field-name="id" - selection-mode="${x => TableRowSelectionMode[x.selectionMode]}" > <${tableColumnTextTag} field-name="firstName" > Name @@ -108,7 +101,7 @@ export const mappingColumn: StoryObj = { <${mappingSpinnerTag} key="calculating" text="Calculating" text-hidden> <${mappingEmptyTag} key="unknown" text="Unknown"> - <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" ?pinned="${x => x.widthMode === 'iconSize'}"> + <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" pinned="${x => x.pinned}"> <${iconChartDiagramChildFocusTag} title="Is child"> <${mappingIconTag} key="false" icon="${iconXmarkTag}" severity="error" text="Not a child" text-hidden> @@ -123,6 +116,11 @@ export const mappingColumn: StoryObj = { `), argTypes: { ...sharedTableArgTypes, + selectionMode: { + table: { + disable: true + } + }, fieldName: { name: 'field-name', description: @@ -145,6 +143,11 @@ export const mappingColumn: StoryObj = { description: widthModeDescription, table: { category: apiCategory.attributes } }, + pinned: { + description: 'When `true`, pin a fixed width column to the left side of the table.', + control: { type: 'boolean' }, + table: { category: apiCategory.attributes } + }, checkValidity: { name: 'checkValidity()', description: checkValidityDescription({ @@ -204,6 +207,7 @@ export const mappingColumn: StoryObj = { fieldName: 'firstName', keyType: 'string', widthMode: 'iconSize', + pinned: false, checkValidity: () => {}, validity: () => {} } From 26e7717a073ed9bc01b86a9ceef30f2609ab3fc9 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 16:07:14 -0500 Subject: [PATCH 09/17] fix test --- .../nimble-angular/table/tests/nimble-table.directive.spec.ts | 1 - .../nimble-components/src/table/components/group-row/styles.ts | 1 - packages/nimble-components/src/table/components/row/styles.ts | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts b/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts index 8d7af13048..47111b5cba 100644 --- a/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts +++ b/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts @@ -303,7 +303,6 @@ describe('Nimble table', () => { expect(directive.parentIdFieldName).toEqual('parentField2'); }); - invalidPinnedColumnConfiguration: false it('can be configured with property binding for selectionMode', () => { expect(directive.selectionMode).toEqual(fixture.componentInstance.selectionMode); diff --git a/packages/nimble-components/src/table/components/group-row/styles.ts b/packages/nimble-components/src/table/components/group-row/styles.ts index 2fa2bf8d92..566a2f2d03 100644 --- a/packages/nimble-components/src/table/components/group-row/styles.ts +++ b/packages/nimble-components/src/table/components/group-row/styles.ts @@ -17,7 +17,6 @@ import { themeBehavior } from '../../../utilities/style/theme'; import { userSelectNone } from '../../../utilities/style/user-select'; import { styles as expandCollapseStyles } from '../../../patterns/expand-collapse/styles'; import { focusVisible } from '../../../utilities/style/focus'; -import { ZIndexLevels } from '../../../utilities/style/types'; export const styles = css` ${display('grid')} diff --git a/packages/nimble-components/src/table/components/row/styles.ts b/packages/nimble-components/src/table/components/row/styles.ts index 95c781efcf..e0d95e1851 100644 --- a/packages/nimble-components/src/table/components/row/styles.ts +++ b/packages/nimble-components/src/table/components/row/styles.ts @@ -19,7 +19,6 @@ import { hexToRgbaCssColor } from '../../../utilities/style/colors'; import { themeBehavior } from '../../../utilities/style/theme'; import { styles as expandCollapseStyles } from '../../../patterns/expand-collapse/styles'; import { focusVisible } from '../../../utilities/style/focus'; -import { ZIndexLevels } from '../../../utilities/style/types'; export const styles = css` ${display('flex')} From a6ce5ba6c145addb50a8e65e54e652942f58eb7c Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 16:22:11 -0500 Subject: [PATCH 10/17] restore accidental delition --- .../nimble-angular/table/tests/nimble-table.directive.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts b/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts index 47111b5cba..7c88209179 100644 --- a/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts +++ b/packages/angular-workspace/nimble-angular/table/tests/nimble-table.directive.spec.ts @@ -302,6 +302,7 @@ describe('Nimble table', () => { fixture.detectChanges(); expect(directive.parentIdFieldName).toEqual('parentField2'); + expect(nativeElement.parentIdFieldName).toEqual('parentField2'); }); it('can be configured with property binding for selectionMode', () => { From 62527b58d65fc3c612a88005ea6490b0cfc89ad6 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 16:36:11 -0500 Subject: [PATCH 11/17] wrappers --- ...ble-table-column-mapping.directive.spec.ts | 32 +++++++++++++++++++ .../nimble-table-column-base.directive.ts | 8 +++++ .../Mapping/NimbleTableColumnMapping.razor | 1 + .../Mapping/NimbleTableColumnMapping.razor.cs | 6 ++++ 4 files changed, 47 insertions(+) diff --git a/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts b/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts index c96ecad232..5a73071e57 100644 --- a/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts +++ b/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts @@ -30,6 +30,7 @@ describe('NimbleTableColumnMapping', () => { action-menu-slot="my-slot" action-menu-label="my menu" column-hidden="true" + pinned fractional-width="2" min-pixel-width="40" sort-direction="${TableColumnSortDirection.ascending}" @@ -93,6 +94,11 @@ describe('NimbleTableColumnMapping', () => { expect(nativeElement.columnHidden).toBe(true); }); + it('will use template string value for pinned', () => { + expect(directive.pinned).toBeTrue(); + expect(nativeElement.pinned).toBeTrue(); + }); + it('will use template string values for sortDirection', () => { expect(directive.sortDirection).toBe(TableColumnSortDirection.ascending); expect(nativeElement.sortDirection).toBe(TableColumnSortDirection.ascending); @@ -146,6 +152,7 @@ describe('NimbleTableColumnMapping', () => { [actionMenuSlot]="actionMenuSlot" [actionMenuLabel]="actionMenuLabel" [column-hidden]="columnHidden" + [pinned]="pinned" [fractional-width]="fractionalWidth" [min-pixel-width]="minPixelWidth" [sort-direction]="sortDirection" @@ -170,6 +177,7 @@ describe('NimbleTableColumnMapping', () => { public minPixelWidth: number | null = 40; public columnId = 'my-column'; public columnHidden = true; + public pinned = false; public sortDirection: TableColumnSortDirection = TableColumnSortDirection.ascending; public sortIndex: number | null = 0; public sortingDisabled = false; @@ -259,6 +267,17 @@ describe('NimbleTableColumnMapping', () => { expect(nativeElement.columnHidden).toBe(false); }); + it('can be configured with property binding for pinned', () => { + expect(directive.pinned).toBeFalse(); + expect(nativeElement.pinned).toBeFalse(); + + fixture.componentInstance.pinned = true; + fixture.detectChanges(); + + expect(directive.pinned).toBeTrue(); + expect(nativeElement.pinned).toBeTrue(); + }); + it('can be configured with property binding for sortDirection', () => { expect(directive.sortDirection).toBe(TableColumnSortDirection.ascending); expect(nativeElement.sortDirection).toBe(TableColumnSortDirection.ascending); @@ -404,6 +423,7 @@ describe('NimbleTableColumnMapping', () => { [attr.action-menu-slot]="actionMenuSlot" [attr.action-menu-label]="actionMenuLabel" [attr.column-hidden]="columnHidden" + [attr.pinned]="pinned" [attr.fractional-width]="fractionalWidth" [attr.min-pixel-width]="minPixelWidth" [attr.sort-direction]="sortDirection" @@ -428,6 +448,7 @@ describe('NimbleTableColumnMapping', () => { public minPixelWidth: number | null = 40; public columnId = 'my-column'; public columnHidden = true; + public pinned = false; public sortDirection: TableColumnSortDirection = TableColumnSortDirection.ascending; public sortIndex: number | null = 0; public sortingDisabled = false; @@ -517,6 +538,17 @@ describe('NimbleTableColumnMapping', () => { expect(nativeElement.columnHidden).toBe(false); }); + it('can be configured with attribute binding for pinned', () => { + expect(directive.pinned).toBeFalse(); + expect(nativeElement.pinned).toBeFalse(); + + fixture.componentInstance.pinned = true; + fixture.detectChanges(); + + expect(directive.pinned).toBeTrue(); + expect(nativeElement.pinned).toBeTrue(); + }); + it('can be configured with attribute binding for sortDirection', () => { expect(directive.sortDirection).toBe(TableColumnSortDirection.ascending); expect(nativeElement.sortDirection).toBe(TableColumnSortDirection.ascending); diff --git a/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts b/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts index 179f3d44c4..dbc6f84184 100644 --- a/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts +++ b/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts @@ -43,6 +43,14 @@ export class NimbleTableColumnBaseDirective { this.renderer.setProperty(this.elementRef.nativeElement, 'columnHidden', toBooleanProperty(value)); } + public get pinned(): boolean { + return this.elementRef.nativeElement.pinned; + } + + @Input('pinned') public set pinned(value: BooleanValueOrAttribute) { + this.renderer.setProperty(this.elementRef.nativeElement, 'pinned', toBooleanProperty(value)); + } + public constructor(protected readonly renderer: Renderer2, protected readonly elementRef: ElementRef) {} public checkValidity(): boolean { diff --git a/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor b/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor index 1a3fb15c42..9779634972 100644 --- a/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor +++ b/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor @@ -11,6 +11,7 @@ column-hidden="@ColumnHidden" fractional-width="@FractionalWidthAsString" min-pixel-width="@MinPixelWidthAsString" + pinned="@Pinned" sort-direction="@SortDirection.ToAttributeValue()" sort-index="@SortIndex" sorting-disabled="@SortingDisabled" diff --git a/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor.cs b/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor.cs index ebc2172bf4..fe707a73df 100644 --- a/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor.cs +++ b/packages/blazor-workspace/NimbleBlazor/Source/TableColumn/Mapping/NimbleTableColumnMapping.razor.cs @@ -17,6 +17,12 @@ public partial class NimbleTableColumnMapping : NimbleTableColumnEnumBase< [Parameter] public double? MinPixelWidth { get; set; } + /// + /// Indicates whether the column is pinned. + /// + [Parameter] + public bool Pinned { get; set; } + /// /// Sets the width mode on the column. /// From e940d6031d2763253bfe854829d20bd69f186ccc Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 16:37:25 -0500 Subject: [PATCH 12/17] Change files --- ...imble-angular-3b488452-3822-410a-a684-15d5f131dd98.json | 7 +++++++ ...nimble-blazor-ef211a30-d326-4325-9b2f-40bad3951887.json | 7 +++++++ ...le-components-817561ce-db7b-4dc2-866f-c794a24b0428.json | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 change/@ni-nimble-angular-3b488452-3822-410a-a684-15d5f131dd98.json create mode 100644 change/@ni-nimble-blazor-ef211a30-d326-4325-9b2f-40bad3951887.json create mode 100644 change/@ni-nimble-components-817561ce-db7b-4dc2-866f-c794a24b0428.json diff --git a/change/@ni-nimble-angular-3b488452-3822-410a-a684-15d5f131dd98.json b/change/@ni-nimble-angular-3b488452-3822-410a-a684-15d5f131dd98.json new file mode 100644 index 0000000000..2e606db68c --- /dev/null +++ b/change/@ni-nimble-angular-3b488452-3822-410a-a684-15d5f131dd98.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "add support for pinning table columns", + "packageName": "@ni/nimble-angular", + "email": "5265744+hellovolcano@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@ni-nimble-blazor-ef211a30-d326-4325-9b2f-40bad3951887.json b/change/@ni-nimble-blazor-ef211a30-d326-4325-9b2f-40bad3951887.json new file mode 100644 index 0000000000..0501942c1e --- /dev/null +++ b/change/@ni-nimble-blazor-ef211a30-d326-4325-9b2f-40bad3951887.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "add support for pinning table columns", + "packageName": "@ni/nimble-blazor", + "email": "5265744+hellovolcano@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@ni-nimble-components-817561ce-db7b-4dc2-866f-c794a24b0428.json b/change/@ni-nimble-components-817561ce-db7b-4dc2-866f-c794a24b0428.json new file mode 100644 index 0000000000..383df5816d --- /dev/null +++ b/change/@ni-nimble-components-817561ce-db7b-4dc2-866f-c794a24b0428.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "add support for pinning table columns", + "packageName": "@ni/nimble-components", + "email": "5265744+hellovolcano@users.noreply.github.com", + "dependentChangeType": "patch" +} From f474d84b65d140cf247d58d090d5d928e11a687b Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 17:11:35 -0500 Subject: [PATCH 13/17] add tests --- .../src/table/tests/table.spec.ts | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/packages/nimble-components/src/table/tests/table.spec.ts b/packages/nimble-components/src/table/tests/table.spec.ts index 3e93476b81..b2b4fbf1a8 100644 --- a/packages/nimble-components/src/table/tests/table.spec.ts +++ b/packages/nimble-components/src/table/tests/table.spec.ts @@ -859,6 +859,88 @@ describe('Table', () => { }); }); + describe('pinned columns', () => { + it('renders pinned columns separately from visible columns', async () => { + column1.columnInternals.currentPixelWidth = 120; + column1.pinned = true; + await connect(); + await waitForUpdatesAsync(); + + expect(element.pinnedColumns).toEqual([column1]); + expect(element.visibleColumns).toEqual([column2]); + expect(element.pinnedColumnOffset).toBe(120); + expect(element.pinnedColumnsGridTemplateColumns).toBe('120px'); + expect( + element.shadowRoot!.querySelector( + '.pinned-columns-header-container' + )!.children.length + ).toBe(1); + expect( + element.shadowRoot!.querySelectorAll( + '.column-headers-container .header-container' + ).length + ).toBe(1); + }); + + it('excludes hidden pinned columns from pinned layout state', async () => { + column1.columnInternals.currentPixelWidth = 120; + column1.pinned = true; + column1.columnHidden = true; + await connect(); + await waitForUpdatesAsync(); + + expect(element.pinnedColumns).toEqual([]); + expect(element.visibleColumns).toEqual([column2]); + expect(element.pinnedColumnOffset).toBe(0); + expect(element.pinnedColumnsGridTemplateColumns).toBe(''); + }); + + it('updates pinned column collections when a pinned column becomes unpinned', async () => { + column1.columnInternals.currentPixelWidth = 120; + column1.pinned = true; + await connect(); + await waitForUpdatesAsync(); + + expect(element.pinnedColumns).toEqual([column1]); + + column1.pinned = false; + await waitForUpdatesAsync(); + + expect(element.pinnedColumns).toEqual([]); + expect(element.visibleColumns).toEqual([column1, column2]); + expect(element.pinnedColumnOffset).toBe(0); + expect(element.pinnedColumnsGridTemplateColumns).toBe(''); + }); + + it('reports invalidPinnedColumnConfiguration when a pinned column has no pixel width', async () => { + await connect(); + + expect(element.checkValidity()).toBeTrue(); + expect(element.validity.invalidPinnedColumnConfiguration).toBeFalse(); + + column1.pinned = true; + await waitForUpdatesAsync(); + + expect(element.checkValidity()).toBeFalse(); + expect(element.validity.invalidPinnedColumnConfiguration).toBeTrue(); + }); + + it('clears invalidPinnedColumnConfiguration when a pinned column gets a pixel width', async () => { + await connect(); + + column1.pinned = true; + await waitForUpdatesAsync(); + expect(element.checkValidity()).toBeFalse(); + expect(element.validity.invalidPinnedColumnConfiguration).toBeTrue(); + + column1.columnInternals.currentPixelWidth = 120; + await waitForUpdatesAsync(); + + expect(element.checkValidity()).toBeTrue(); + expect(element.validity.invalidPinnedColumnConfiguration).toBeFalse(); + }); + }); + describe('multiple updates', () => { it('can update action menu slots and column sort', async () => { await element.setData(simpleTableData); From 17b823c2ee38fd4a43eadde4dbf5f77fcaadf0a9 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Thu, 28 May 2026 18:25:18 -0500 Subject: [PATCH 14/17] fix ordering of pinned column --- packages/nimble-components/src/table/components/row/styles.ts | 2 ++ packages/nimble-components/src/table/styles.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/nimble-components/src/table/components/row/styles.ts b/packages/nimble-components/src/table/components/row/styles.ts index e0d95e1851..031bb942aa 100644 --- a/packages/nimble-components/src/table/components/row/styles.ts +++ b/packages/nimble-components/src/table/components/row/styles.ts @@ -19,6 +19,7 @@ import { hexToRgbaCssColor } from '../../../utilities/style/colors'; import { themeBehavior } from '../../../utilities/style/theme'; import { styles as expandCollapseStyles } from '../../../patterns/expand-collapse/styles'; import { focusVisible } from '../../../utilities/style/focus'; +import { ZIndexLevels } from '../../../utilities/style/types'; export const styles = css` ${display('flex')} @@ -121,6 +122,7 @@ export const styles = css` position: sticky; left: 0; background: ${applicationBackgroundColor}; + z-index: ${ZIndexLevels.zIndex1000}; } .cell-container { diff --git a/packages/nimble-components/src/table/styles.ts b/packages/nimble-components/src/table/styles.ts index ed60699a6e..6f5ed27e96 100644 --- a/packages/nimble-components/src/table/styles.ts +++ b/packages/nimble-components/src/table/styles.ts @@ -127,6 +127,7 @@ export const styles = css` position: sticky; left: 0; background: ${applicationBackgroundColor}; + z-index: ${ZIndexLevels.zIndex1000}; } .header-container { From f322f1cae9526abd31c79f0057cea6f1995a7318 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Fri, 29 May 2026 11:39:07 -0500 Subject: [PATCH 15/17] make pinned an attribute --- .../tests/nimble-table-column-mapping.directive.spec.ts | 7 ++++--- .../table-column/nimble-table-column-base.directive.ts | 2 +- .../src/table-column/base/tests/table-column.spec.ts | 7 +++++++ .../table-column/mapping/table-column-mapping.stories.ts | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts b/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts index 5a73071e57..41953d2bf0 100644 --- a/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts +++ b/packages/angular-workspace/nimble-angular/table-column/mapping/tests/nimble-table-column-mapping.directive.spec.ts @@ -1,5 +1,6 @@ import { Component, ElementRef, ViewChild } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import type { BooleanValueOrAttribute } from '@ni/nimble-angular/internal-utilities'; import { NimbleTableModule } from '../../../table/nimble-table.module'; import { NimbleTableColumnMappingModule } from '../nimble-table-column-mapping.module'; import { NimbleTableColumnMappingDirective, type TableColumnMapping, TableColumnMappingWidthMode } from '../nimble-table-column-mapping.directive'; @@ -177,7 +178,7 @@ describe('NimbleTableColumnMapping', () => { public minPixelWidth: number | null = 40; public columnId = 'my-column'; public columnHidden = true; - public pinned = false; + public pinned: BooleanValueOrAttribute = null; public sortDirection: TableColumnSortDirection = TableColumnSortDirection.ascending; public sortIndex: number | null = 0; public sortingDisabled = false; @@ -448,7 +449,7 @@ describe('NimbleTableColumnMapping', () => { public minPixelWidth: number | null = 40; public columnId = 'my-column'; public columnHidden = true; - public pinned = false; + public pinned: BooleanValueOrAttribute = null; public sortDirection: TableColumnSortDirection = TableColumnSortDirection.ascending; public sortIndex: number | null = 0; public sortingDisabled = false; @@ -542,7 +543,7 @@ describe('NimbleTableColumnMapping', () => { expect(directive.pinned).toBeFalse(); expect(nativeElement.pinned).toBeFalse(); - fixture.componentInstance.pinned = true; + fixture.componentInstance.pinned = ''; fixture.detectChanges(); expect(directive.pinned).toBeTrue(); diff --git a/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts b/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts index dbc6f84184..16b9f05350 100644 --- a/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts +++ b/packages/angular-workspace/nimble-angular/table-column/nimble-table-column-base.directive.ts @@ -43,7 +43,7 @@ export class NimbleTableColumnBaseDirective { this.renderer.setProperty(this.elementRef.nativeElement, 'columnHidden', toBooleanProperty(value)); } - public get pinned(): boolean { + public get pinned(): BooleanValueOrAttribute { return this.elementRef.nativeElement.pinned; } diff --git a/packages/nimble-components/src/table-column/base/tests/table-column.spec.ts b/packages/nimble-components/src/table-column/base/tests/table-column.spec.ts index a18b8ff8d9..a605bced28 100644 --- a/packages/nimble-components/src/table-column/base/tests/table-column.spec.ts +++ b/packages/nimble-components/src/table-column/base/tests/table-column.spec.ts @@ -55,6 +55,13 @@ describe('TableColumn', () => { expect(element.columnInternals.currentPixelWidth).toBe(200); }); + it('has expected defaults for pinned', async () => { + await connect(); + + expect(element.pinned).toBeFalse(); + expect(element.hasAttribute('pinned')).toBeFalse(); + }); + describe('with a custom constructor', () => { // Seems subject to change how errors are handled during custom // element construction: https://github.com/WICG/webcomponents/issues/635 diff --git a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts index 89f7b9d6bc..5e8101b90e 100644 --- a/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts +++ b/packages/storybook/src/nimble/table-column/mapping/table-column-mapping.stories.ts @@ -101,7 +101,7 @@ export const mappingColumn: StoryObj = { <${mappingSpinnerTag} key="calculating" text="Calculating" text-hidden> <${mappingEmptyTag} key="unknown" text="Unknown"> - <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" pinned="${x => x.pinned}"> + <${tableColumnMappingTag} field-name="isChild" key-type="boolean" width-mode="${x => TableColumnMappingWidthMode[x.widthMode]}" ?pinned="${x => x.pinned}"> <${iconChartDiagramChildFocusTag} title="Is child"> <${mappingIconTag} key="false" icon="${iconXmarkTag}" severity="error" text="Not a child" text-hidden> From f5a00a47c43e577b6f8bf11587c9150bd13879a7 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Fri, 29 May 2026 12:54:19 -0500 Subject: [PATCH 16/17] fix for styling non-pinned chevron --- .../src/table/components/group-row/styles.ts | 36 +++++++++++++++++-- .../table/components/group-row/template.ts | 6 ++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/packages/nimble-components/src/table/components/group-row/styles.ts b/packages/nimble-components/src/table/components/group-row/styles.ts index 566a2f2d03..d2effffc48 100644 --- a/packages/nimble-components/src/table/components/group-row/styles.ts +++ b/packages/nimble-components/src/table/components/group-row/styles.ts @@ -17,6 +17,7 @@ import { themeBehavior } from '../../../utilities/style/theme'; import { userSelectNone } from '../../../utilities/style/user-select'; import { styles as expandCollapseStyles } from '../../../patterns/expand-collapse/styles'; import { focusVisible } from '../../../utilities/style/focus'; +import { ZIndexLevels } from '../../../utilities/style/types'; export const styles = css` ${display('grid')} @@ -65,16 +66,30 @@ export const styles = css` } .pinned-column-spacer { + height: 100%; + } + + .pinned-column-spacer.has-pinned-columns { position: sticky; left: 0; background: ${tableRowBorderColor}; - height: 100%; + z-index: ${ZIndexLevels.zIndex1000}; } - .expand-collapse-button-container { + .expand-collapse-button-container.has-pinned-columns { + position: sticky; + left: var(--ni-private-table-group-row-pinned-column-offset); + z-index: ${ZIndexLevels.zIndex1000}; background: ${tableRowBorderColor}; } + .expand-collapse-button-container.selectable.has-pinned-columns { + left: calc( + var(--ni-private-table-group-row-pinned-column-offset) + + ${controlHeight} + ); + } + .expand-collapse-button-container.selectable { } @@ -107,6 +122,13 @@ export const styles = css` display: flex; } + .checkbox-container.has-pinned-columns { + position: sticky; + left: var(--ni-private-table-group-row-pinned-column-offset); + z-index: ${ZIndexLevels.zIndex1000}; + background: ${tableRowBorderColor}; + } + .selection-checkbox { margin-left: ${standardPadding}; } @@ -121,6 +143,16 @@ export const styles = css` :host([allow-hover]:hover)::before { background-color: ${hexToRgbaCssColor(White, 0.05)}; } + + .pinned-column-spacer.has-pinned-columns, + .expand-collapse-button-container.has-pinned-columns, + .checkbox-container.has-pinned-columns { + background: linear-gradient( + ${hexToRgbaCssColor(White, 0.1)}, + ${hexToRgbaCssColor(White, 0.1)} + ), + ${tableRowBorderColor}; + } ` ), themeBehavior( diff --git a/packages/nimble-components/src/table/components/group-row/template.ts b/packages/nimble-components/src/table/components/group-row/template.ts index 2985242b67..c87663566c 100644 --- a/packages/nimble-components/src/table/components/group-row/template.ts +++ b/packages/nimble-components/src/table/components/group-row/template.ts @@ -20,10 +20,10 @@ export const template = html` --ni-private-table-group-row-pinned-column-offset: ${x => x.pinnedColumnOffset}px; " > - + ${when(x => x.selectable, html` - + <${checkboxTag} ${ref('selectionCheckbox')} class="selection-checkbox" @@ -36,7 +36,7 @@ export const template = html` `)} - + <${buttonTag} appearance="${ButtonAppearance.ghost}" content-hidden From 22eedc5437c5b882737231b275745a20788631e1 Mon Sep 17 00:00:00 2001 From: Valerie Gleason <5265744+hellovolcano@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:01:34 -0500 Subject: [PATCH 17/17] fix hover/sticky group issue --- .../src/table/components/group-row/styles.ts | 43 ++++++++++++------- .../table/components/group-row/template.ts | 2 +- .../src/table/components/row/styles.ts | 42 ++++++++++++++++++ 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/packages/nimble-components/src/table/components/group-row/styles.ts b/packages/nimble-components/src/table/components/group-row/styles.ts index d2effffc48..abf69c1f2c 100644 --- a/packages/nimble-components/src/table/components/group-row/styles.ts +++ b/packages/nimble-components/src/table/components/group-row/styles.ts @@ -60,6 +60,12 @@ export const styles = css` background-color: ${fillHoverColor}; } + :host([allow-hover]:hover) .pinned-column-spacer.has-pinned-columns, + :host([allow-hover]:hover) .checkbox-container.has-pinned-columns { + background: linear-gradient(${fillHoverColor}, ${fillHoverColor}), + ${tableRowBorderColor}; + } + :host(${focusVisible}) { outline: calc(2 * ${borderWidth}) solid ${borderHoverColor}; outline-offset: calc(-2 * ${borderWidth}); @@ -76,20 +82,6 @@ export const styles = css` z-index: ${ZIndexLevels.zIndex1000}; } - .expand-collapse-button-container.has-pinned-columns { - position: sticky; - left: var(--ni-private-table-group-row-pinned-column-offset); - z-index: ${ZIndexLevels.zIndex1000}; - background: ${tableRowBorderColor}; - } - - .expand-collapse-button-container.selectable.has-pinned-columns { - left: calc( - var(--ni-private-table-group-row-pinned-column-offset) + - ${controlHeight} - ); - } - .expand-collapse-button-container.selectable { } @@ -144,8 +136,20 @@ export const styles = css` background-color: ${hexToRgbaCssColor(White, 0.05)}; } + :host([allow-hover]:hover) .pinned-column-spacer.has-pinned-columns, + :host([allow-hover]:hover) .checkbox-container.has-pinned-columns { + background: linear-gradient( + ${hexToRgbaCssColor(White, 0.05)}, + ${hexToRgbaCssColor(White, 0.05)} + ), + linear-gradient( + ${hexToRgbaCssColor(White, 0.1)}, + ${hexToRgbaCssColor(White, 0.1)} + ), + ${tableRowBorderColor}; + } + .pinned-column-spacer.has-pinned-columns, - .expand-collapse-button-container.has-pinned-columns, .checkbox-container.has-pinned-columns { background: linear-gradient( ${hexToRgbaCssColor(White, 0.1)}, @@ -161,6 +165,15 @@ export const styles = css` :host([allow-hover]:hover)::before { background-color: ${hexToRgbaCssColor(White, 0.1)}; } + + :host([allow-hover]:hover) .pinned-column-spacer.has-pinned-columns, + :host([allow-hover]:hover) .checkbox-container.has-pinned-columns { + background: linear-gradient( + ${hexToRgbaCssColor(White, 0.1)}, + ${hexToRgbaCssColor(White, 0.1)} + ), + ${tableRowBorderColor}; + } ` ) ); diff --git a/packages/nimble-components/src/table/components/group-row/template.ts b/packages/nimble-components/src/table/components/group-row/template.ts index c87663566c..07ab43c2dd 100644 --- a/packages/nimble-components/src/table/components/group-row/template.ts +++ b/packages/nimble-components/src/table/components/group-row/template.ts @@ -36,7 +36,7 @@ export const template = html` `)} - + <${buttonTag} appearance="${ButtonAppearance.ghost}" content-hidden diff --git a/packages/nimble-components/src/table/components/row/styles.ts b/packages/nimble-components/src/table/components/row/styles.ts index 031bb942aa..506d9524df 100644 --- a/packages/nimble-components/src/table/components/row/styles.ts +++ b/packages/nimble-components/src/table/components/row/styles.ts @@ -55,6 +55,24 @@ export const styles = css` background-color: ${fillHoverSelectedColor}; } + :host([selectable]:not([selected])[allow-hover]:hover) .pinned-cell-container { + background: linear-gradient(${fillHoverColor}, ${fillHoverColor}), + ${applicationBackgroundColor}; + } + + :host([selected]) .pinned-cell-container { + background: linear-gradient(${fillSelectedColor}, ${fillSelectedColor}), + ${applicationBackgroundColor}; + } + + :host([selected][allow-hover]:hover) .pinned-cell-container { + background: linear-gradient( + ${fillHoverSelectedColor}, + ${fillHoverSelectedColor} + ), + ${applicationBackgroundColor}; + } + :host(${focusVisible}) { outline: none; box-shadow: @@ -203,6 +221,30 @@ export const styles = css` :host([selected][allow-hover]:hover)::before { background-color: ${hexToRgbaCssColor(White, 0.2)}; } + + :host([selectable]:not([selected])[allow-hover]:hover) .pinned-cell-container { + background: linear-gradient( + ${hexToRgbaCssColor(White, 0.05)}, + ${hexToRgbaCssColor(White, 0.05)} + ), + ${applicationBackgroundColor}; + } + + :host([selected]) .pinned-cell-container { + background: linear-gradient( + ${hexToRgbaCssColor(White, 0.25)}, + ${hexToRgbaCssColor(White, 0.25)} + ), + ${applicationBackgroundColor}; + } + + :host([selected][allow-hover]:hover) .pinned-cell-container { + background: linear-gradient( + ${hexToRgbaCssColor(White, 0.2)}, + ${hexToRgbaCssColor(White, 0.2)} + ), + ${applicationBackgroundColor}; + } ` ) );