diff --git a/.changeset/itchy-oranges-live.md b/.changeset/itchy-oranges-live.md new file mode 100644 index 00000000000..bfaa4b67814 --- /dev/null +++ b/.changeset/itchy-oranges-live.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Reimplemented tooltips using the Popover API. Bumped styled-components to 5.x. diff --git a/package-lock.json b/package-lock.json index 078a8b20250..4a4b895885b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@github/paste-markdown": "^1.4.0", "@github/relative-time-element": "^4.1.2", "@lit-labs/react": "1.1.1", + "@oddbird/popover-polyfill": "0.0.6", "@primer/behaviors": "1.3.2", "@primer/octicons-react": "^17.7.0", "@primer/primitives": "7.10.0", @@ -3044,9 +3045,9 @@ "dev": true }, "node_modules/@github/combobox-nav": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.1.7.tgz", - "integrity": "sha512-Webx0W5iTpkk5Chy9dB/1BEUORQ0qrwui8HaaVBiy75W2VOJg96WTuKj1rXENAJ3XTMhdEF53bn0LYfvP0EKvg==" + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.1.5.tgz", + "integrity": "sha512-dmG1PuppNKHnBBEcfylWDwj9SSxd/E/qd8mC1G/klQC3s7ps5q6JZ034mwkkG0LKfI+Y+UgEua/ROD776N400w==" }, "node_modules/@github/markdown-toolbar-element": { "version": "2.1.1", @@ -6214,6 +6215,11 @@ "node": ">=10" } }, + "node_modules/@oddbird/popover-polyfill": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@oddbird/popover-polyfill/-/popover-polyfill-0.0.6.tgz", + "integrity": "sha512-5FvK3gk3qrFwupHWXK8vVZqDL44S7KulWc4JcasGPTxjbxNQSA3tkSGaX1JKpoaaOeG/uHslehsEdDhCJnf+Rw==" + }, "node_modules/@playwright/test": { "version": "1.27.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz", @@ -15477,6 +15483,40 @@ "url": "https://opencollective.com/storybook" } }, + "node_modules/@storybook/core-server/node_modules/@storybook/csf-tools": { + "version": "6.5.15", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.15.tgz", + "integrity": "sha512-2LwSD7yE/ccXBc58K4vdKw/oJJg6IpC4WD51rBt2mAl5JUCkxhOq7wG/Z8Wy1lZw2LVuKNTmjVou5blGRI/bTg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.10", + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/plugin-transform-react-jsx": "^7.12.12", + "@babel/preset-env": "^7.12.11", + "@babel/traverse": "^7.12.11", + "@babel/types": "^7.12.11", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/mdx1-csf": "^0.0.1", + "core-js": "^3.8.2", + "fs-extra": "^9.0.1", + "global": "^4.4.0", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "@storybook/mdx2-csf": "^0.0.3" + }, + "peerDependenciesMeta": { + "@storybook/mdx2-csf": { + "optional": true + } + } + }, "node_modules/@storybook/core-server/node_modules/@storybook/node-logger": { "version": "6.5.15", "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.5.15.tgz", @@ -16122,9 +16162,9 @@ "dev": true }, "node_modules/@storybook/core-server/node_modules/node-fetch": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", - "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "dev": true, "dependencies": { "whatwg-url": "^5.0.0" @@ -16872,9 +16912,9 @@ } }, "node_modules/@storybook/csf-tools": { - "version": "6.5.15", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.15.tgz", - "integrity": "sha512-2LwSD7yE/ccXBc58K4vdKw/oJJg6IpC4WD51rBt2mAl5JUCkxhOq7wG/Z8Wy1lZw2LVuKNTmjVou5blGRI/bTg==", + "version": "6.5.16", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.16.tgz", + "integrity": "sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A==", "dev": true, "dependencies": { "@babel/core": "^7.12.10", @@ -18209,9 +18249,9 @@ "dev": true }, "node_modules/@storybook/manager-webpack4/node_modules/node-fetch": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", - "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "dev": true, "dependencies": { "whatwg-url": "^5.0.0" @@ -27866,10 +27906,13 @@ } }, "node_modules/camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/can-bind-to-host": { "version": "1.1.2", @@ -29496,7 +29539,7 @@ "node_modules/css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", "dev": true, "engines": { "node": ">=4" @@ -31130,54 +31173,6 @@ "esbuild-windows-arm64": "0.14.39" } }, - "node_modules/esbuild-android-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.39.tgz", - "integrity": "sha512-EJOu04p9WgZk0UoKTqLId9VnIsotmI/Z98EXrKURGb3LPNunkeffqQIkjS2cAvidh+OK5uVrXaIP229zK6GvhQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-android-arm64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.39.tgz", - "integrity": "sha512-+twajJqO7n3MrCz9e+2lVOnFplRsaGRwsq1KL/uOy7xK7QdRSprRQcObGDeDZUZsacD5gUkk6OiHiYp6RzU3CA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-darwin-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.39.tgz", - "integrity": "sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/esbuild-darwin-arm64": { "version": "0.14.39", "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.39.tgz", @@ -31194,86 +31189,6 @@ "node": ">=12" } }, - "node_modules/esbuild-freebsd-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.39.tgz", - "integrity": "sha512-oMNH8lJI4wtgN5oxuFP7BQ22vgB/e3Tl5Woehcd6i2r6F3TszpCnNl8wo2d/KvyQ4zvLvCWAlRciumhQg88+kQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-freebsd-arm64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.39.tgz", - "integrity": "sha512-1GHK7kwk57ukY2yI4ILWKJXaxfr+8HcM/r/JKCGCPziIVlL+Wi7RbJ2OzMcTKZ1HpvEqCTBT/J6cO4ZEwW4Ypg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-32": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.39.tgz", - "integrity": "sha512-g97Sbb6g4zfRLIxHgW2pc393DjnkTRMeq3N1rmjDUABxpx8SjocK4jLen+/mq55G46eE2TA0MkJ4R3SpKMu7dg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.39.tgz", - "integrity": "sha512-4tcgFDYWdI+UbNMGlua9u1Zhu0N5R6u9tl5WOM8aVnNX143JZoBZLpCuUr5lCKhnD0SCO+5gUyMfupGrHtfggQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-arm": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.39.tgz", - "integrity": "sha512-t0Hn1kWVx5UpCzAJkKRfHeYOLyFnXwYynIkK54/h3tbMweGI7dj400D1k0Vvtj2u1P+JTRT9tx3AjtLEMmfVBQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/esbuild-linux-arm64": { "version": "0.14.39", "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.39.tgz", @@ -31290,70 +31205,6 @@ "node": ">=12" } }, - "node_modules/esbuild-linux-mips64le": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.39.tgz", - "integrity": "sha512-epwlYgVdbmkuRr5n4es3B+yDI0I2e/nxhKejT9H0OLxFAlMkeQZxSpxATpDc9m8NqRci6Kwyb/SfmD1koG2Zuw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-ppc64le": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.39.tgz", - "integrity": "sha512-W/5ezaq+rQiQBThIjLMNjsuhPHg+ApVAdTz2LvcuesZFMsJoQAW2hutoyg47XxpWi7aEjJGrkS26qCJKhRn3QQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-riscv64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.39.tgz", - "integrity": "sha512-IS48xeokcCTKeQIOke2O0t9t14HPvwnZcy+5baG13Z1wxs9ZrC5ig5ypEQQh4QMKxURD5TpCLHw2W42CLuVZaA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-linux-s390x": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.39.tgz", - "integrity": "sha512-zEfunpqR8sMomqXhNTFEKDs+ik7HC01m3M60MsEjZOqaywHu5e5682fMsqOlZbesEAAaO9aAtRBsU7CHnSZWyA==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/esbuild-loader": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.19.0.tgz", @@ -31419,102 +31270,6 @@ "node": ">=10.13.0" } }, - "node_modules/esbuild-netbsd-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.39.tgz", - "integrity": "sha512-Uo2suJBSIlrZCe4E0k75VDIFJWfZy+bOV6ih3T4MVMRJh1lHJ2UyGoaX4bOxomYN3t+IakHPyEoln1+qJ1qYaA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-openbsd-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.39.tgz", - "integrity": "sha512-secQU+EpgUPpYjJe3OecoeGKVvRMLeKUxSMGHnK+aK5uQM3n1FPXNJzyz1LHFOo0WOyw+uoCxBYdM4O10oaCAA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-sunos-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.39.tgz", - "integrity": "sha512-qHq0t5gePEDm2nqZLb+35p/qkaXVS7oIe32R0ECh2HOdiXXkj/1uQI9IRogGqKkK+QjDG+DhwiUw7QoHur/Rwg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-32": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.39.tgz", - "integrity": "sha512-XPjwp2OgtEX0JnOlTgT6E5txbRp6Uw54Isorm3CwOtloJazeIWXuiwK0ONJBVb/CGbiCpS7iP2UahGgd2p1x+Q==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.39.tgz", - "integrity": "sha512-E2wm+5FwCcLpKsBHRw28bSYQw0Ikxb7zIMxw3OPAkiaQhLVr3dnVO8DofmbWhhf6b97bWzg37iSZ45ZDpLw7Ow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild-windows-arm64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.39.tgz", - "integrity": "sha512-sBZQz5D+Gd0EQ09tZRnz/PpVdLwvp/ufMtJ1iDFYddDaPpZXKqPyaxfYBLs3ueiaksQ26GGa7sci0OqFzNs7KA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -51421,13 +51176,10 @@ } }, "node_modules/tar/node_modules/minipass": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", - "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.2.tgz", + "integrity": "sha512-4Hbzei7ZyBp+1aw0874YWpKOubZd/jc53/XU+gkYry1QV+VvrbO8icLM5CUtm4F0hyXn85DXYKEMIS26gitD3A==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { "node": ">=8" } @@ -56485,9 +56237,9 @@ "dev": true }, "@github/combobox-nav": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.1.7.tgz", - "integrity": "sha512-Webx0W5iTpkk5Chy9dB/1BEUORQ0qrwui8HaaVBiy75W2VOJg96WTuKj1rXENAJ3XTMhdEF53bn0LYfvP0EKvg==" + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@github/combobox-nav/-/combobox-nav-2.1.5.tgz", + "integrity": "sha512-dmG1PuppNKHnBBEcfylWDwj9SSxd/E/qd8mC1G/klQC3s7ps5q6JZ034mwkkG0LKfI+Y+UgEua/ROD776N400w==" }, "@github/markdown-toolbar-element": { "version": "2.1.1", @@ -58956,6 +58708,11 @@ } } }, + "@oddbird/popover-polyfill": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@oddbird/popover-polyfill/-/popover-polyfill-0.0.6.tgz", + "integrity": "sha512-5FvK3gk3qrFwupHWXK8vVZqDL44S7KulWc4JcasGPTxjbxNQSA3tkSGaX1JKpoaaOeG/uHslehsEdDhCJnf+Rw==" + }, "@playwright/test": { "version": "1.27.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz", @@ -65958,6 +65715,28 @@ "core-js": "^3.8.2" } }, + "@storybook/csf-tools": { + "version": "6.5.15", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.15.tgz", + "integrity": "sha512-2LwSD7yE/ccXBc58K4vdKw/oJJg6IpC4WD51rBt2mAl5JUCkxhOq7wG/Z8Wy1lZw2LVuKNTmjVou5blGRI/bTg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.10", + "@babel/generator": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/plugin-transform-react-jsx": "^7.12.12", + "@babel/preset-env": "^7.12.11", + "@babel/traverse": "^7.12.11", + "@babel/types": "^7.12.11", + "@storybook/csf": "0.0.2--canary.4566f4d.1", + "@storybook/mdx1-csf": "^0.0.1", + "core-js": "^3.8.2", + "fs-extra": "^9.0.1", + "global": "^4.4.0", + "regenerator-runtime": "^0.13.7", + "ts-dedent": "^2.0.0" + } + }, "@storybook/node-logger": { "version": "6.5.15", "resolved": "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.5.15.tgz", @@ -66460,9 +66239,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", - "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "dev": true, "requires": { "whatwg-url": "^5.0.0" @@ -66746,9 +66525,9 @@ } }, "@storybook/csf-tools": { - "version": "6.5.15", - "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.15.tgz", - "integrity": "sha512-2LwSD7yE/ccXBc58K4vdKw/oJJg6IpC4WD51rBt2mAl5JUCkxhOq7wG/Z8Wy1lZw2LVuKNTmjVou5blGRI/bTg==", + "version": "6.5.16", + "resolved": "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.16.tgz", + "integrity": "sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A==", "dev": true, "requires": { "@babel/core": "^7.12.10", @@ -67771,9 +67550,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.8.tgz", - "integrity": "sha512-RZ6dBYuj8dRSfxpUSu+NsdF1dpPpluJxwOp+6IoDp/sH2QNDSvurYsAa+F1WxY2RjA1iP93xhcsUoYbF2XBqVg==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", + "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", "dev": true, "requires": { "whatwg-url": "^5.0.0" @@ -75242,9 +75021,9 @@ } }, "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", "dev": true }, "can-bind-to-host": { @@ -76494,7 +76273,7 @@ "css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", "dev": true }, "css-loader": { @@ -77803,27 +77582,6 @@ "esbuild-windows-arm64": "0.14.39" } }, - "esbuild-android-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.39.tgz", - "integrity": "sha512-EJOu04p9WgZk0UoKTqLId9VnIsotmI/Z98EXrKURGb3LPNunkeffqQIkjS2cAvidh+OK5uVrXaIP229zK6GvhQ==", - "dev": true, - "optional": true - }, - "esbuild-android-arm64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.39.tgz", - "integrity": "sha512-+twajJqO7n3MrCz9e+2lVOnFplRsaGRwsq1KL/uOy7xK7QdRSprRQcObGDeDZUZsacD5gUkk6OiHiYp6RzU3CA==", - "dev": true, - "optional": true - }, - "esbuild-darwin-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.39.tgz", - "integrity": "sha512-ImT6eUw3kcGcHoUxEcdBpi6LfTRWaV6+qf32iYYAfwOeV+XaQ/Xp5XQIBiijLeo+LpGci9M0FVec09nUw41a5g==", - "dev": true, - "optional": true - }, "esbuild-darwin-arm64": { "version": "0.14.39", "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.39.tgz", @@ -77831,41 +77589,6 @@ "dev": true, "optional": true }, - "esbuild-freebsd-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.39.tgz", - "integrity": "sha512-oMNH8lJI4wtgN5oxuFP7BQ22vgB/e3Tl5Woehcd6i2r6F3TszpCnNl8wo2d/KvyQ4zvLvCWAlRciumhQg88+kQ==", - "dev": true, - "optional": true - }, - "esbuild-freebsd-arm64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.39.tgz", - "integrity": "sha512-1GHK7kwk57ukY2yI4ILWKJXaxfr+8HcM/r/JKCGCPziIVlL+Wi7RbJ2OzMcTKZ1HpvEqCTBT/J6cO4ZEwW4Ypg==", - "dev": true, - "optional": true - }, - "esbuild-linux-32": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.39.tgz", - "integrity": "sha512-g97Sbb6g4zfRLIxHgW2pc393DjnkTRMeq3N1rmjDUABxpx8SjocK4jLen+/mq55G46eE2TA0MkJ4R3SpKMu7dg==", - "dev": true, - "optional": true - }, - "esbuild-linux-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.39.tgz", - "integrity": "sha512-4tcgFDYWdI+UbNMGlua9u1Zhu0N5R6u9tl5WOM8aVnNX143JZoBZLpCuUr5lCKhnD0SCO+5gUyMfupGrHtfggQ==", - "dev": true, - "optional": true - }, - "esbuild-linux-arm": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.39.tgz", - "integrity": "sha512-t0Hn1kWVx5UpCzAJkKRfHeYOLyFnXwYynIkK54/h3tbMweGI7dj400D1k0Vvtj2u1P+JTRT9tx3AjtLEMmfVBQ==", - "dev": true, - "optional": true - }, "esbuild-linux-arm64": { "version": "0.14.39", "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.39.tgz", @@ -77873,34 +77596,6 @@ "dev": true, "optional": true }, - "esbuild-linux-mips64le": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.39.tgz", - "integrity": "sha512-epwlYgVdbmkuRr5n4es3B+yDI0I2e/nxhKejT9H0OLxFAlMkeQZxSpxATpDc9m8NqRci6Kwyb/SfmD1koG2Zuw==", - "dev": true, - "optional": true - }, - "esbuild-linux-ppc64le": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.39.tgz", - "integrity": "sha512-W/5ezaq+rQiQBThIjLMNjsuhPHg+ApVAdTz2LvcuesZFMsJoQAW2hutoyg47XxpWi7aEjJGrkS26qCJKhRn3QQ==", - "dev": true, - "optional": true - }, - "esbuild-linux-riscv64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.39.tgz", - "integrity": "sha512-IS48xeokcCTKeQIOke2O0t9t14HPvwnZcy+5baG13Z1wxs9ZrC5ig5ypEQQh4QMKxURD5TpCLHw2W42CLuVZaA==", - "dev": true, - "optional": true - }, - "esbuild-linux-s390x": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.39.tgz", - "integrity": "sha512-zEfunpqR8sMomqXhNTFEKDs+ik7HC01m3M60MsEjZOqaywHu5e5682fMsqOlZbesEAAaO9aAtRBsU7CHnSZWyA==", - "dev": true, - "optional": true - }, "esbuild-loader": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-2.19.0.tgz", @@ -77950,48 +77645,6 @@ } } }, - "esbuild-netbsd-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.39.tgz", - "integrity": "sha512-Uo2suJBSIlrZCe4E0k75VDIFJWfZy+bOV6ih3T4MVMRJh1lHJ2UyGoaX4bOxomYN3t+IakHPyEoln1+qJ1qYaA==", - "dev": true, - "optional": true - }, - "esbuild-openbsd-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.39.tgz", - "integrity": "sha512-secQU+EpgUPpYjJe3OecoeGKVvRMLeKUxSMGHnK+aK5uQM3n1FPXNJzyz1LHFOo0WOyw+uoCxBYdM4O10oaCAA==", - "dev": true, - "optional": true - }, - "esbuild-sunos-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.39.tgz", - "integrity": "sha512-qHq0t5gePEDm2nqZLb+35p/qkaXVS7oIe32R0ECh2HOdiXXkj/1uQI9IRogGqKkK+QjDG+DhwiUw7QoHur/Rwg==", - "dev": true, - "optional": true - }, - "esbuild-windows-32": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.39.tgz", - "integrity": "sha512-XPjwp2OgtEX0JnOlTgT6E5txbRp6Uw54Isorm3CwOtloJazeIWXuiwK0ONJBVb/CGbiCpS7iP2UahGgd2p1x+Q==", - "dev": true, - "optional": true - }, - "esbuild-windows-64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.39.tgz", - "integrity": "sha512-E2wm+5FwCcLpKsBHRw28bSYQw0Ikxb7zIMxw3OPAkiaQhLVr3dnVO8DofmbWhhf6b97bWzg37iSZ45ZDpLw7Ow==", - "dev": true, - "optional": true - }, - "esbuild-windows-arm64": { - "version": "0.14.39", - "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.39.tgz", - "integrity": "sha512-sBZQz5D+Gd0EQ09tZRnz/PpVdLwvp/ufMtJ1iDFYddDaPpZXKqPyaxfYBLs3ueiaksQ26GGa7sci0OqFzNs7KA==", - "dev": true, - "optional": true - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -93033,13 +92686,10 @@ "dev": true }, "minipass": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.0.tgz", - "integrity": "sha512-g2Uuh2jEKoht+zvO6vJqXmYpflPqzRBT+Th2h01DKh5z7wbY/AZ2gCQ78cP70YoHPyFdY30YBV5WxgLOEwOykw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.0.2.tgz", + "integrity": "sha512-4Hbzei7ZyBp+1aw0874YWpKOubZd/jc53/XU+gkYry1QV+VvrbO8icLM5CUtm4F0hyXn85DXYKEMIS26gitD3A==", + "dev": true }, "mkdirp": { "version": "1.0.4", diff --git a/package.json b/package.json index 2e6b4e38469..74ef92aff74 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "@github/markdown-toolbar-element": "^2.1.0", "@github/paste-markdown": "^1.4.0", "@github/relative-time-element": "^4.1.2", + "@oddbird/popover-polyfill": "0.0.6", "@lit-labs/react": "1.1.1", "@primer/behaviors": "1.3.2", "@primer/octicons-react": "^17.7.0", diff --git a/src/BaseStyles.tsx b/src/BaseStyles.tsx index 48796eaf93a..250840b999b 100644 --- a/src/BaseStyles.tsx +++ b/src/BaseStyles.tsx @@ -26,6 +26,30 @@ const GlobalStyle = createGlobalStyle<{colorScheme?: 'light' | 'dark'}>` details-dialog:focus:not(:focus-visible):not(.focus-visible) { outline: none; } + + /* Popover API Polyfill */ + [popover] { + position: fixed; + z-index: 2147483647; + inset: 0; + padding: 0.25em; + width: fit-content; + height: fit-content; + border: solid; + background: canvas; + color: canvastext; + overflow: auto; + margin: auto; + } + [popover]:not(.\:open) { + display: none; + } + [popover][anchor] { + inset: auto; + } + [popover]:not(:-internal-popover-hidden) { + display: block; + } ` const Base = styled.div` diff --git a/src/Tooltip.tsx b/src/Tooltip.tsx index 28fb1c8645f..dbf88ccdf4e 100644 --- a/src/Tooltip.tsx +++ b/src/Tooltip.tsx @@ -1,266 +1,272 @@ -import classnames from 'classnames' import React from 'react' import styled from 'styled-components' import {get} from './constants' import sx, {SxProp} from './sx' import {ComponentProps} from './utils/types' - -const TooltipBase = styled.span` - position: relative; - - &::before { - position: absolute; - z-index: 1000001; - display: none; - width: 0px; - height: 0px; - color: ${get('colors.neutral.emphasisPlus')}; - pointer-events: none; - content: ''; - border: 6px solid transparent; - opacity: 0; - } - - &::after { - position: absolute; - z-index: 1000000; +import classNames from 'classnames' +import '@oddbird/popover-polyfill' + +type PopoverProps = { + popover?: 'auto' +} & SxProp + +const TooltipBase = styled('span') + .withConfig({ + shouldForwardProp: (prop, defaultValidatorFn) => ['popover'].includes(prop) || defaultValidatorFn(prop), + }) + .attrs(props => ({ + popover: props.popover, + id: props.id, + }))` + /* Without the triple ampersands, the specificity of these styles are overridden by the base popover styles. + * https://styled-components.com/docs/faqs#how-can-i-override-styles-with-higher-specificity + */ + &&& { + border: none; + overflow: hidden; + margin: 0; + position: fixed; + background: transparent; + top: 0; + left: 0; display: none; - padding: 0.5em 0.75em; - font: normal normal 11px/1.5 ${get('fonts.normal')}; - -webkit-font-smoothing: subpixel-antialiased; - color: ${get('colors.fg.onEmphasis')}; - text-align: center; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-wrap: break-word; - white-space: pre; - pointer-events: none; - content: attr(aria-label); - background: ${get('colors.neutral.emphasisPlus')}; - border-radius: ${get('radii.1')}; opacity: 0; - } - - // delay animation for tooltip - @keyframes tooltip-appear { - from { - opacity: 0; - } - - to { - opacity: 1; + padding: 0; + --width: 0; + --height: 0; + --anchor-width: 0; + + @keyframes tooltip-appear { + from { + opacity: 0; + } + + to { + opacity: 1; + } } - } - &:hover, - &:active, - &:focus, - &:focus-within { - &::before, - &::after { - display: inline-block; - text-decoration: none; - animation-name: tooltip-appear; - animation-duration: 0.1s; - animation-fill-mode: forwards; - animation-timing-function: ease-in; - animation-delay: 0.4s; - } - } + animation-name: tooltip-appear; + animation-duration: 0.1s; + animation-fill-mode: forwards; + animation-timing-function: ease-in; + animation-delay: 0.4s; - &.tooltipped-no-delay:hover, - &.tooltipped-no-delay:active, - &.tooltipped-no-delay:focus, - &.tooltipped-no-delay:focus-within { - &::before, - &::after { + &.tooltipped-no-delay { animation-delay: 0s; } - } - &.tooltipped-multiline:hover, - &.tooltipped-multiline:active, - &.tooltipped-multiline:focus, - &.tooltipped-multiline:focus-within { - &::after { - display: table-cell; + &.\\:open { + display: block; } - } - // Tooltipped south - &.tooltipped-s, - &.tooltipped-se, - &.tooltipped-sw { - &::after { - top: 100%; - right: 50%; - margin-top: 6px; + &:open { + display: block; } &::before { - top: auto; - right: 50%; - bottom: -7px; - margin-right: -6px; - border-bottom-color: ${get('colors.neutral.emphasisPlus')}; - } - } - - &.tooltipped-se { - &::after { - right: auto; - left: 50%; - margin-left: -${get('space.3')}; + position: relative; + padding: 0.5em 0.75em; + border-radius: ${get('radii.1')}; + font: normal normal 11px/1.5 ${get('fonts.normal')}; + background: ${get('colors.neutral.emphasisPlus')}; + color: ${get('colors.fg.onEmphasis')}; + content: attr(aria-label); + word-wrap: break-word; + text-align: center; + display: block; } - } - - &.tooltipped-sw::after { - margin-right: -${get('space.3')}; - } - // Tooltips above the object - &.tooltipped-n, - &.tooltipped-ne, - &.tooltipped-nw { &::after { + position: absolute; + content: ''; right: 50%; - bottom: 100%; - margin-bottom: 6px; - } - - &::before { - top: -7px; - right: 50%; - bottom: auto; margin-right: -6px; - border-top-color: ${get('colors.neutral.emphasisPlus')}; + width: 0; + height: 0; + border: 6px solid transparent; } - } - - &.tooltipped-ne { - &::after { - right: auto; - left: 50%; - margin-left: -${get('space.3')}; - } - } - &.tooltipped-nw::after { - margin-right: -${get('space.3')}; - } - - // Move the tooltip body to the center of the object. - &.tooltipped-s::after, - &.tooltipped-n::after { - transform: translateX(50%); - } + &.tooltipped-n, + &.tooltipped-ne, + &.tooltipped-nw { + padding-bottom: 10px; - // Tooltipped to the left - &.tooltipped-w { - &::after { - right: 100%; - bottom: 50%; - margin-right: 6px; - transform: translateY(50%); + &::after { + top: calc(var(--height) - 12px); + border-top-color: ${get('colors.neutral.emphasisPlus')}; + } } - &::before { - top: 50%; - bottom: 50%; - left: -7px; - margin-top: -6px; - border-left-color: ${get('colors.neutral.emphasisPlus')}; + &.tooltipped-nw { + &::after { + right: 0.5em; + } } - } - // tooltipped to the right - &.tooltipped-e { - &::after { - bottom: 50%; - left: 100%; - margin-left: 6px; - transform: translateY(50%); + &.tooltipped-ne { + &::after { + left: 0.5em; + } } - &::before { - top: 50%; - right: -7px; - bottom: 50%; - margin-top: -6px; - border-right-color: ${get('colors.neutral.emphasisPlus')}; + &.tooltipped-sw { + padding-top: 10px; + &::after { + right: 0.5em; + top: 0; + border-bottom-color: ${get('colors.neutral.emphasisPlus')}; + } } - } - &.tooltipped-multiline { - &::after { - width: max-content; - max-width: 250px; - word-wrap: break-word; - white-space: pre-line; - border-collapse: separate; + &.tooltipped-se { + padding-top: 10px; + &::after { + left: 0.5em; + top: 0; + border-bottom-color: ${get('colors.neutral.emphasisPlus')}; + } } - &.tooltipped-s::after, - &.tooltipped-n::after { - right: auto; - left: 50%; - transform: translateX(-50%); - } + &.tooltipped-s { + padding-top: 10px; - &.tooltipped-w::after, - &.tooltipped-e::after { - right: 100%; + &::after { + top: 0; + border-bottom-color: ${get('colors.neutral.emphasisPlus')}; + } } - } - &.tooltipped-align-right-2::after { - right: 0; - margin-right: 0; - } + &.tooltipped-e { + padding-left: 10px; - &.tooltipped-align-right-2::before { - right: 15px; - } + &:after { + top: calc(var(--height) / 2 - 5px); + right: calc(var(--width) - 5px); + border-right-color: ${get('colors.neutral.emphasisPlus')}; + } + } - &.tooltipped-align-left-2::after { - left: 0; - margin-left: 0; - } + &.tooltipped-w { + padding-right: 10px; + &::after { + top: calc(var(--height) / 2 - 5px); + right: 4px; + border-left-color: ${get('colors.neutral.emphasisPlus')}; + } + } - &.tooltipped-align-left-2::before { - left: 10px; + &.tooltipped-multiline { + &::before { + width: max-content; + max-width: 250px; + word-wrap: break-word; + white-space: pre-line; + border-collapse: separate; + } + } + ${sx} } - - ${sx}; ` export type TooltipProps = { direction?: 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw' text?: string noDelay?: boolean - align?: 'left' | 'right' wrap?: boolean } & ComponentProps -function Tooltip({direction = 'n', children, className, text, noDelay, align, wrap, ...rest}: TooltipProps) { - const classes = classnames( +const Tooltip = ({ + direction = 'n', + children, + className, + noDelay, + text, + wrap, + popover = 'auto', + ...rest +}: TooltipProps) => { + const classes = classNames( className, `tooltipped-${direction}`, - align && `tooltipped-align-${align}-2`, noDelay && 'tooltipped-no-delay', wrap && 'tooltipped-multiline', ) + + const popoverRef = React.useRef(null) + + const [showTooltip, setShowTooltip] = React.useState(false) + + const handlePointerEnter = (event: React.PointerEvent | React.FocusEvent) => { + const anchored = popoverRef.current + if (anchored !== null && !showTooltip) { + anchored.showPopover() + anchored.style.setProperty('--width', `${anchored.clientWidth}px`) + anchored.style.setProperty('--height', `${anchored.clientHeight}px`) + + const anchor = event.currentTarget as HTMLElement + const {top, left, width, height} = anchor.getBoundingClientRect() + anchored.style.setProperty('--anchor-width', `${width}px`) + let [_top, _left] = [0, 0] + + if (direction === 'n' || direction === 'ne' || direction === 'nw') { + _top = top - anchored.clientHeight + _left = left - anchored.clientWidth / 2 + width / 2 + } + + if (direction === 's' || direction === 'sw' || direction === 'se') { + _top = top + anchored.clientHeight / 2 + _left = left - anchored.clientWidth / 2 + width / 2 + } + + if (direction === 'e' || direction === 'w') { + _top = top - (anchored.clientHeight - height) / 2 + } + + if (direction === 'nw' || direction === 'sw') { + _left = left + width - anchored.clientWidth + } + + if (direction === 'w') { + _left = left - anchored.clientWidth + } + + if (direction === 'se' || direction === 'ne') { + _left = left + } + + if (direction === 'e') { + _left = left + width + } + + anchored.style.setProperty('top', `${_top}px`) + anchored.style.setProperty('left', `${_left}px`) + setShowTooltip(true) + } + } + + const handlePointerLeave = () => { + const anchored = popoverRef.current + if (anchored !== null && showTooltip) { + anchored.hidePopover() + setShowTooltip(false) + } + } + return ( - + {children} - + + ) } -Tooltip.alignments = ['left', 'right'] - -Tooltip.directions = ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'] +Tooltip.directions = ['n', 'ne', 'nw', 's', 'se', 'sw', 'e', 'w'] export default Tooltip diff --git a/src/__tests__/Tooltip.test.tsx b/src/__tests__/Tooltip.test.tsx index 2f96bfb1728..88b6fc4f13e 100644 --- a/src/__tests__/Tooltip.test.tsx +++ b/src/__tests__/Tooltip.test.tsx @@ -1,13 +1,14 @@ import React from 'react' import Tooltip, {TooltipProps} from '../Tooltip' -import {render, renderClasses, rendersClass, behavesAsComponent, checkExports} from '../utils/testing' +import {ReactTestRendererJSON} from 'react-test-renderer' +import {render, childRenderClasses, childRendersClass, behavesAsComponent, checkExports} from '../utils/testing' import {render as HTMLRender} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' expect.extend(toHaveNoViolations) describe('Tooltip', () => { - behavesAsComponent({Component: Tooltip}) + behavesAsComponent({Component: Tooltip, options: {skipAs: true}}) checkExports('Tooltip', { default: Tooltip, @@ -21,31 +22,32 @@ describe('Tooltip', () => { it('renders a with the "tooltipped" class', () => { expect(render().type).toEqual('span') - expect(renderClasses()).toContain('tooltipped-n') - }) - - it('respects the "align" prop', () => { - expect(rendersClass(, 'tooltipped-align-left-2')).toBe(true) - expect(rendersClass(, 'tooltipped-align-right-2')).toBe(true) + expect(childRenderClasses(, -1)).toContain('tooltipped-n') }) it('respects the "direction" prop', () => { for (const direction of Tooltip.directions) { expect( - rendersClass(, `tooltipped-${direction}`), + childRendersClass( + , + `tooltipped-${direction}`, + -1, + ), ).toBe(true) } }) it('respects the "noDelay" prop', () => { - expect(rendersClass(, 'tooltipped-no-delay')).toBe(true) + expect(childRendersClass(, 'tooltipped-no-delay', -1)).toBe(true) }) it('respects the "text" prop', () => { - expect(render().props['aria-label']).toEqual('hi') + const tooltip = render() as ReactTestRendererJSON + const child = tooltip.children?.at(-1) as ReactTestRendererJSON + expect(child.props['aria-label']).toEqual('hi') }) it('respects the "wrap" prop', () => { - expect(rendersClass(, 'tooltipped-multiline')).toBe(true) + expect(childRendersClass(, 'tooltipped-multiline', -1)).toBe(true) }) }) diff --git a/src/__tests__/__snapshots__/TextInput.test.tsx.snap b/src/__tests__/__snapshots__/TextInput.test.tsx.snap index 31051ce5700..1140fcb0867 100644 --- a/src/__tests__/__snapshots__/TextInput.test.tsx.snap +++ b/src/__tests__/__snapshots__/TextInput.test.tsx.snap @@ -1258,7 +1258,7 @@ exports[`TextInput renders trailingAction icon button 1`] = ` line-height: 0; } -.c4 { +.c3 { border-radius: 6px; border: 1px solid; border-color: transparent; @@ -1303,59 +1303,59 @@ exports[`TextInput renders trailingAction icon button 1`] = ` box-shadow: none; } -.c4:focus:not(:disabled) { +.c3:focus:not(:disabled) { box-shadow: none; outline: 2px solid #0969da; outline-offset: -2px; } -.c4:focus:not(:disabled):not(:focus-visible) { +.c3:focus:not(:disabled):not(:focus-visible) { outline: solid 1px transparent; } -.c4:focus-visible:not(:disabled) { +.c3:focus-visible:not(:disabled) { box-shadow: none; outline: 2px solid #0969da; outline-offset: -2px; } -.c4[href] { +.c3[href] { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; } -.c4[href]:hover { +.c3[href]:hover { -webkit-text-decoration: none; text-decoration: none; } -.c4:hover { +.c3:hover { -webkit-transition-duration: 80ms; transition-duration: 80ms; } -.c4:active { +.c3:active { -webkit-transition: none; transition: none; } -.c4:disabled { +.c3:disabled { cursor: not-allowed; box-shadow: none; color: #8c959f; } -.c4:disabled [data-component=ButtonCounter] { +.c3:disabled [data-component=ButtonCounter] { color: inherit; } -.c4 [data-component=ButtonCounter] { +.c3 [data-component=ButtonCounter] { font-size: 14px; } -.c4[data-component=IconButton] { +.c3[data-component=IconButton] { display: inline-grid; padding: unset; place-content: center; @@ -1363,68 +1363,68 @@ exports[`TextInput renders trailingAction icon button 1`] = ` min-width: unset; } -.c4[data-size="small"] { +.c3[data-size="small"] { padding: 0 8px; height: 28px; gap: 4px; font-size: 12px; } -.c4[data-size="small"] [data-component="text"] { +.c3[data-size="small"] [data-component="text"] { line-height: calc(20 / 12); } -.c4[data-size="small"] [data-component=ButtonCounter] { +.c3[data-size="small"] [data-component=ButtonCounter] { font-size: 12px; } -.c4[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { +.c3[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { margin-right: 4px; } -.c4[data-size="small"][data-component=IconButton] { +.c3[data-size="small"][data-component=IconButton] { width: 28px; padding: unset; } -.c4[data-size="large"] { +.c3[data-size="large"] { padding: 0 16px; height: 40px; gap: 8px; } -.c4[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { +.c3[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { margin-right: 8px; } -.c4[data-size="large"][data-component=IconButton] { +.c3[data-size="large"][data-component=IconButton] { width: 40px; padding: unset; } -.c4[data-block="block"] { +.c3[data-block="block"] { width: 100%; } -.c4 [data-component="leadingVisual"] { +.c3 [data-component="leadingVisual"] { grid-area: leadingVisual; } -.c4 [data-component="text"] { +.c3 [data-component="text"] { grid-area: text; line-height: calc(20/14); white-space: nowrap; } -.c4 [data-component="trailingVisual"] { +.c3 [data-component="trailingVisual"] { grid-area: trailingVisual; } -.c4 [data-component="trailingAction"] { +.c3 [data-component="trailingAction"] { margin-right: -4px; } -.c4 [data-component="buttonContent"] { +.c3 [data-component="buttonContent"] { -webkit-flex: 1 0 auto; -ms-flex: 1 0 auto; flex: 1 0 auto; @@ -1440,35 +1440,35 @@ exports[`TextInput renders trailingAction icon button 1`] = ` align-content: center; } -.c4 [data-component="buttonContent"] > :not(:last-child) { +.c3 [data-component="buttonContent"] > :not(:last-child) { margin-right: 8px; } -.c4:hover:not([disabled]) { +.c3:hover:not([disabled]) { background-color: #f3f4f6; } -.c4:active:not([disabled]) { +.c3:active:not([disabled]) { background-color: hsla(220,14%,94%,1); } -.c4[aria-expanded=true] { +.c3[aria-expanded=true] { background-color: hsla(220,14%,94%,1); } -.c4 svg { +.c3 svg { color: #57606a; } -.c4[data-no-visuals] { +.c3[data-no-visuals] { color: #0969da; } -.c4:has([data-component="ButtonCounter"]) { +.c3:has([data-component="ButtonCounter"]) { color: #0969da; } -.c4[data-size="small"][data-no-visuals="true"] { +.c3[data-size="small"][data-no-visuals="true"] { padding-top: 2px; padding-right: 4px; padding-bottom: 2px; @@ -1476,7 +1476,7 @@ exports[`TextInput renders trailingAction icon button 1`] = ` position: relative; } -.c4[data-size="small"][data-no-visuals="true"][data-component="IconButton"] { +.c3[data-size="small"][data-no-visuals="true"][data-component="IconButton"] { width: var(--inner-action-size); height: var(--inner-action-size); } @@ -1570,60 +1570,20 @@ exports[`TextInput renders trailingAction icon button 1`] = ` outline: 0; } -.c3 { - position: relative; -} - -.c3::before { - position: absolute; - z-index: 1000001; +.c4.c4.c4 { + border: none; + overflow: hidden; + margin: 0; + position: fixed; + background: transparent; + top: 0; + left: 0; display: none; - width: 0px; - height: 0px; - color: #24292f; - pointer-events: none; - content: ''; - border: 6px solid transparent; opacity: 0; -} - -.c3::after { - position: absolute; - z-index: 1000000; - display: none; - padding: 0.5em 0.75em; - font: normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; - -webkit-font-smoothing: subpixel-antialiased; - color: #ffffff; - text-align: center; - -webkit-text-decoration: none; - text-decoration: none; - text-shadow: none; - text-transform: none; - -webkit-letter-spacing: normal; - -moz-letter-spacing: normal; - -ms-letter-spacing: normal; - letter-spacing: normal; - word-wrap: break-word; - white-space: pre; - pointer-events: none; - content: attr(aria-label); - background: #24292f; - border-radius: 3px; - opacity: 0; -} - -.c3:hover::before, -.c3:active::before, -.c3:focus::before, -.c3:focus-within::before, -.c3:hover::after, -.c3:active::after, -.c3:focus::after, -.c3:focus-within::after { - display: inline-block; - -webkit-text-decoration: none; - text-decoration: none; + padding: 0; + --width: 0; + --height: 0; + --anchor-width: 0; -webkit-animation-name: tooltip-appear; animation-name: tooltip-appear; -webkit-animation-duration: 0.1s; @@ -1636,123 +1596,113 @@ exports[`TextInput renders trailingAction icon button 1`] = ` animation-delay: 0.4s; } -.c3.tooltipped-no-delay:hover::before, -.c3.tooltipped-no-delay:active::before, -.c3.tooltipped-no-delay:focus::before, -.c3.tooltipped-no-delay:focus-within::before, -.c3.tooltipped-no-delay:hover::after, -.c3.tooltipped-no-delay:active::after, -.c3.tooltipped-no-delay:focus::after, -.c3.tooltipped-no-delay:focus-within::after { +.c4.c4.c4.tooltipped-no-delay { -webkit-animation-delay: 0s; animation-delay: 0s; } -.c3.tooltipped-multiline:hover::after, -.c3.tooltipped-multiline:active::after, -.c3.tooltipped-multiline:focus::after, -.c3.tooltipped-multiline:focus-within::after { - display: table-cell; +.c4.c4.c4.\\:open { + display: block; } -.c3.tooltipped-s::after, -.c3.tooltipped-se::after, -.c3.tooltipped-sw::after { - top: 100%; - right: 50%; - margin-top: 6px; +.c4.c4.c4:open { + display: block; } -.c3.tooltipped-s::before, -.c3.tooltipped-se::before, -.c3.tooltipped-sw::before { - top: auto; +.c4.c4.c4::before { + position: relative; + padding: 0.5em 0.75em; + border-radius: 3px; + font: normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; + background: #24292f; + color: #ffffff; + content: attr(aria-label); + word-wrap: break-word; + text-align: center; + display: block; +} + +.c4.c4.c4::after { + position: absolute; + content: ''; right: 50%; - bottom: -7px; margin-right: -6px; - border-bottom-color: #24292f; + width: 0; + height: 0; + border: 6px solid transparent; } -.c3.tooltipped-se::after { - right: auto; - left: 50%; - margin-left: -16px; +.c4.c4.c4.tooltipped-n, +.c4.c4.c4.tooltipped-ne, +.c4.c4.c4.tooltipped-nw { + padding-bottom: 10px; } -.c3.tooltipped-sw::after { - margin-right: -16px; +.c4.c4.c4.tooltipped-n::after, +.c4.c4.c4.tooltipped-ne::after, +.c4.c4.c4.tooltipped-nw::after { + top: calc(var(--height) - 12px); + border-top-color: #24292f; } -.c3.tooltipped-n::after, -.c3.tooltipped-ne::after, -.c3.tooltipped-nw::after { - right: 50%; - bottom: 100%; - margin-bottom: 6px; +.c4.c4.c4.tooltipped-nw::after { + right: 0.5em; } -.c3.tooltipped-n::before, -.c3.tooltipped-ne::before, -.c3.tooltipped-nw::before { - top: -7px; - right: 50%; - bottom: auto; - margin-right: -6px; - border-top-color: #24292f; +.c4.c4.c4.tooltipped-ne::after { + left: 0.5em; +} + +.c4.c4.c4.tooltipped-sw { + padding-top: 10px; } -.c3.tooltipped-ne::after { - right: auto; - left: 50%; - margin-left: -16px; +.c4.c4.c4.tooltipped-sw::after { + right: 0.5em; + top: 0; + border-bottom-color: #24292f; } -.c3.tooltipped-nw::after { - margin-right: -16px; +.c4.c4.c4.tooltipped-se { + padding-top: 10px; } -.c3.tooltipped-s::after, -.c3.tooltipped-n::after { - -webkit-transform: translateX(50%); - -ms-transform: translateX(50%); - transform: translateX(50%); +.c4.c4.c4.tooltipped-se::after { + left: 0.5em; + top: 0; + border-bottom-color: #24292f; } -.c3.tooltipped-w::after { - right: 100%; - bottom: 50%; - margin-right: 6px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%); +.c4.c4.c4.tooltipped-s { + padding-top: 10px; } -.c3.tooltipped-w::before { - top: 50%; - bottom: 50%; - left: -7px; - margin-top: -6px; - border-left-color: #24292f; +.c4.c4.c4.tooltipped-s::after { + top: 0; + border-bottom-color: #24292f; } -.c3.tooltipped-e::after { - bottom: 50%; - left: 100%; - margin-left: 6px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%); +.c4.c4.c4.tooltipped-e { + padding-left: 10px; } -.c3.tooltipped-e::before { - top: 50%; - right: -7px; - bottom: 50%; - margin-top: -6px; +.c4.c4.c4.tooltipped-e:after { + top: calc(var(--height) / 2 - 5px); + right: calc(var(--width) - 5px); border-right-color: #24292f; } -.c3.tooltipped-multiline::after { +.c4.c4.c4.tooltipped-w { + padding-right: 10px; +} + +.c4.c4.c4.tooltipped-w::after { + top: calc(var(--height) / 2 - 5px); + right: 4px; + border-left-color: #24292f; +} + +.c4.c4.c4.tooltipped-multiline::before { width: -webkit-max-content; width: -moz-max-content; width: max-content; @@ -1762,46 +1712,14 @@ exports[`TextInput renders trailingAction icon button 1`] = ` border-collapse: separate; } -.c3.tooltipped-multiline.tooltipped-s::after, -.c3.tooltipped-multiline.tooltipped-n::after { - right: auto; - left: 50%; - -webkit-transform: translateX(-50%); - -ms-transform: translateX(-50%); - transform: translateX(-50%); -} - -.c3.tooltipped-multiline.tooltipped-w::after, -.c3.tooltipped-multiline.tooltipped-e::after { - right: 100%; -} - -.c3.tooltipped-align-right-2::after { - right: 0; - margin-right: 0; -} - -.c3.tooltipped-align-right-2::before { - right: 15px; -} - -.c3.tooltipped-align-left-2::after { - left: 0; - margin-left: 0; -} - -.c3.tooltipped-align-left-2::before { - left: 10px; -} - @media (forced-colors:active) { - .c4:focus { + .c3:focus { outline: solid 1px transparent; } } @media (pointer:coarse) { - .c4[data-size="small"][data-no-visuals="true"]:after { + .c3[data-size="small"][data-no-visuals="true"]:after { content: ""; position: absolute; left: 0; @@ -1839,13 +1757,19 @@ exports[`TextInput renders trailingAction icon button 1`] = ` className="c2 TextInput-action" > + @@ -2281,14 +2209,14 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` line-height: 0; } -.c5 { +.c4 { -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; } -.c4 { +.c3 { border-radius: 6px; border: 1px solid; border-color: transparent; @@ -2333,59 +2261,59 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` box-shadow: none; } -.c4:focus:not(:disabled) { +.c3:focus:not(:disabled) { box-shadow: none; outline: 2px solid #0969da; outline-offset: -2px; } -.c4:focus:not(:disabled):not(:focus-visible) { +.c3:focus:not(:disabled):not(:focus-visible) { outline: solid 1px transparent; } -.c4:focus-visible:not(:disabled) { +.c3:focus-visible:not(:disabled) { box-shadow: none; outline: 2px solid #0969da; outline-offset: -2px; } -.c4[href] { +.c3[href] { display: -webkit-inline-box; display: -webkit-inline-flex; display: -ms-inline-flexbox; display: inline-flex; } -.c4[href]:hover { +.c3[href]:hover { -webkit-text-decoration: none; text-decoration: none; } -.c4:hover { +.c3:hover { -webkit-transition-duration: 80ms; transition-duration: 80ms; } -.c4:active { +.c3:active { -webkit-transition: none; transition: none; } -.c4:disabled { +.c3:disabled { cursor: not-allowed; box-shadow: none; color: #8c959f; } -.c4:disabled [data-component=ButtonCounter] { +.c3:disabled [data-component=ButtonCounter] { color: inherit; } -.c4 [data-component=ButtonCounter] { +.c3 [data-component=ButtonCounter] { font-size: 14px; } -.c4[data-component=IconButton] { +.c3[data-component=IconButton] { display: inline-grid; padding: unset; place-content: center; @@ -2393,68 +2321,68 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` min-width: unset; } -.c4[data-size="small"] { +.c3[data-size="small"] { padding: 0 8px; height: 28px; gap: 4px; font-size: 12px; } -.c4[data-size="small"] [data-component="text"] { +.c3[data-size="small"] [data-component="text"] { line-height: calc(20 / 12); } -.c4[data-size="small"] [data-component=ButtonCounter] { +.c3[data-size="small"] [data-component=ButtonCounter] { font-size: 12px; } -.c4[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { +.c3[data-size="small"] [data-component="buttonContent"] > :not(:last-child) { margin-right: 4px; } -.c4[data-size="small"][data-component=IconButton] { +.c3[data-size="small"][data-component=IconButton] { width: 28px; padding: unset; } -.c4[data-size="large"] { +.c3[data-size="large"] { padding: 0 16px; height: 40px; gap: 8px; } -.c4[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { +.c3[data-size="large"] [data-component="buttonContent"] > :not(:last-child) { margin-right: 8px; } -.c4[data-size="large"][data-component=IconButton] { +.c3[data-size="large"][data-component=IconButton] { width: 40px; padding: unset; } -.c4[data-block="block"] { +.c3[data-block="block"] { width: 100%; } -.c4 [data-component="leadingVisual"] { +.c3 [data-component="leadingVisual"] { grid-area: leadingVisual; } -.c4 [data-component="text"] { +.c3 [data-component="text"] { grid-area: text; line-height: calc(20/14); white-space: nowrap; } -.c4 [data-component="trailingVisual"] { +.c3 [data-component="trailingVisual"] { grid-area: trailingVisual; } -.c4 [data-component="trailingAction"] { +.c3 [data-component="trailingAction"] { margin-right: -4px; } -.c4 [data-component="buttonContent"] { +.c3 [data-component="buttonContent"] { -webkit-flex: 1 0 auto; -ms-flex: 1 0 auto; flex: 1 0 auto; @@ -2470,35 +2398,35 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` align-content: center; } -.c4 [data-component="buttonContent"] > :not(:last-child) { +.c3 [data-component="buttonContent"] > :not(:last-child) { margin-right: 8px; } -.c4:hover:not([disabled]) { +.c3:hover:not([disabled]) { background-color: #f3f4f6; } -.c4:active:not([disabled]) { +.c3:active:not([disabled]) { background-color: hsla(220,14%,94%,1); } -.c4[aria-expanded=true] { +.c3[aria-expanded=true] { background-color: hsla(220,14%,94%,1); } -.c4 svg { +.c3 svg { color: #57606a; } -.c4[data-no-visuals] { +.c3[data-no-visuals] { color: #0969da; } -.c4:has([data-component="ButtonCounter"]) { +.c3:has([data-component="ButtonCounter"]) { color: #0969da; } -.c4[data-no-visuals="true"] { +.c3[data-no-visuals="true"] { padding-top: 2px; padding-right: 4px; padding-bottom: 2px; @@ -2506,7 +2434,7 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` position: relative; } -.c4[data-no-visuals="true"][data-component="IconButton"] { +.c3[data-no-visuals="true"][data-component="IconButton"] { width: var(--inner-action-size); height: var(--inner-action-size); } @@ -2600,61 +2528,20 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` outline: 0; } -.c3 { - position: relative; - display: inline-block; -} - -.c3::before { - position: absolute; - z-index: 1000001; +.c5.c5.c5 { + border: none; + overflow: hidden; + margin: 0; + position: fixed; + background: transparent; + top: 0; + left: 0; display: none; - width: 0px; - height: 0px; - color: #24292f; - pointer-events: none; - content: ''; - border: 6px solid transparent; opacity: 0; -} - -.c3::after { - position: absolute; - z-index: 1000000; - display: none; - padding: 0.5em 0.75em; - font: normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; - -webkit-font-smoothing: subpixel-antialiased; - color: #ffffff; - text-align: center; - -webkit-text-decoration: none; - text-decoration: none; - text-shadow: none; - text-transform: none; - -webkit-letter-spacing: normal; - -moz-letter-spacing: normal; - -ms-letter-spacing: normal; - letter-spacing: normal; - word-wrap: break-word; - white-space: pre; - pointer-events: none; - content: attr(aria-label); - background: #24292f; - border-radius: 3px; - opacity: 0; -} - -.c3:hover::before, -.c3:active::before, -.c3:focus::before, -.c3:focus-within::before, -.c3:hover::after, -.c3:active::after, -.c3:focus::after, -.c3:focus-within::after { - display: inline-block; - -webkit-text-decoration: none; - text-decoration: none; + padding: 0; + --width: 0; + --height: 0; + --anchor-width: 0; -webkit-animation-name: tooltip-appear; animation-name: tooltip-appear; -webkit-animation-duration: 0.1s; @@ -2665,125 +2552,116 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` animation-timing-function: ease-in; -webkit-animation-delay: 0.4s; animation-delay: 0.4s; + display: inline-block; } -.c3.tooltipped-no-delay:hover::before, -.c3.tooltipped-no-delay:active::before, -.c3.tooltipped-no-delay:focus::before, -.c3.tooltipped-no-delay:focus-within::before, -.c3.tooltipped-no-delay:hover::after, -.c3.tooltipped-no-delay:active::after, -.c3.tooltipped-no-delay:focus::after, -.c3.tooltipped-no-delay:focus-within::after { +.c5.c5.c5.tooltipped-no-delay { -webkit-animation-delay: 0s; animation-delay: 0s; } -.c3.tooltipped-multiline:hover::after, -.c3.tooltipped-multiline:active::after, -.c3.tooltipped-multiline:focus::after, -.c3.tooltipped-multiline:focus-within::after { - display: table-cell; +.c5.c5.c5.\\:open { + display: block; } -.c3.tooltipped-s::after, -.c3.tooltipped-se::after, -.c3.tooltipped-sw::after { - top: 100%; - right: 50%; - margin-top: 6px; +.c5.c5.c5:open { + display: block; } -.c3.tooltipped-s::before, -.c3.tooltipped-se::before, -.c3.tooltipped-sw::before { - top: auto; +.c5.c5.c5::before { + position: relative; + padding: 0.5em 0.75em; + border-radius: 3px; + font: normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; + background: #24292f; + color: #ffffff; + content: attr(aria-label); + word-wrap: break-word; + text-align: center; + display: block; +} + +.c5.c5.c5::after { + position: absolute; + content: ''; right: 50%; - bottom: -7px; margin-right: -6px; - border-bottom-color: #24292f; + width: 0; + height: 0; + border: 6px solid transparent; } -.c3.tooltipped-se::after { - right: auto; - left: 50%; - margin-left: -16px; +.c5.c5.c5.tooltipped-n, +.c5.c5.c5.tooltipped-ne, +.c5.c5.c5.tooltipped-nw { + padding-bottom: 10px; } -.c3.tooltipped-sw::after { - margin-right: -16px; +.c5.c5.c5.tooltipped-n::after, +.c5.c5.c5.tooltipped-ne::after, +.c5.c5.c5.tooltipped-nw::after { + top: calc(var(--height) - 12px); + border-top-color: #24292f; } -.c3.tooltipped-n::after, -.c3.tooltipped-ne::after, -.c3.tooltipped-nw::after { - right: 50%; - bottom: 100%; - margin-bottom: 6px; +.c5.c5.c5.tooltipped-nw::after { + right: 0.5em; } -.c3.tooltipped-n::before, -.c3.tooltipped-ne::before, -.c3.tooltipped-nw::before { - top: -7px; - right: 50%; - bottom: auto; - margin-right: -6px; - border-top-color: #24292f; +.c5.c5.c5.tooltipped-ne::after { + left: 0.5em; } -.c3.tooltipped-ne::after { - right: auto; - left: 50%; - margin-left: -16px; +.c5.c5.c5.tooltipped-sw { + padding-top: 10px; +} + +.c5.c5.c5.tooltipped-sw::after { + right: 0.5em; + top: 0; + border-bottom-color: #24292f; } -.c3.tooltipped-nw::after { - margin-right: -16px; +.c5.c5.c5.tooltipped-se { + padding-top: 10px; } -.c3.tooltipped-s::after, -.c3.tooltipped-n::after { - -webkit-transform: translateX(50%); - -ms-transform: translateX(50%); - transform: translateX(50%); +.c5.c5.c5.tooltipped-se::after { + left: 0.5em; + top: 0; + border-bottom-color: #24292f; } -.c3.tooltipped-w::after { - right: 100%; - bottom: 50%; - margin-right: 6px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%); +.c5.c5.c5.tooltipped-s { + padding-top: 10px; } -.c3.tooltipped-w::before { - top: 50%; - bottom: 50%; - left: -7px; - margin-top: -6px; - border-left-color: #24292f; +.c5.c5.c5.tooltipped-s::after { + top: 0; + border-bottom-color: #24292f; } -.c3.tooltipped-e::after { - bottom: 50%; - left: 100%; - margin-left: 6px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%); +.c5.c5.c5.tooltipped-e { + padding-left: 10px; } -.c3.tooltipped-e::before { - top: 50%; - right: -7px; - bottom: 50%; - margin-top: -6px; +.c5.c5.c5.tooltipped-e:after { + top: calc(var(--height) / 2 - 5px); + right: calc(var(--width) - 5px); border-right-color: #24292f; } -.c3.tooltipped-multiline::after { +.c5.c5.c5.tooltipped-w { + padding-right: 10px; +} + +.c5.c5.c5.tooltipped-w::after { + top: calc(var(--height) / 2 - 5px); + right: 4px; + border-left-color: #24292f; +} + +.c5.c5.c5.tooltipped-multiline::before { width: -webkit-max-content; width: -moz-max-content; width: max-content; @@ -2793,46 +2671,14 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` border-collapse: separate; } -.c3.tooltipped-multiline.tooltipped-s::after, -.c3.tooltipped-multiline.tooltipped-n::after { - right: auto; - left: 50%; - -webkit-transform: translateX(-50%); - -ms-transform: translateX(-50%); - transform: translateX(-50%); -} - -.c3.tooltipped-multiline.tooltipped-w::after, -.c3.tooltipped-multiline.tooltipped-e::after { - right: 100%; -} - -.c3.tooltipped-align-right-2::after { - right: 0; - margin-right: 0; -} - -.c3.tooltipped-align-right-2::before { - right: 15px; -} - -.c3.tooltipped-align-left-2::after { - left: 0; - margin-left: 0; -} - -.c3.tooltipped-align-left-2::before { - left: 10px; -} - @media (forced-colors:active) { - .c4:focus { + .c3:focus { outline: solid 1px transparent; } } @media (pointer:coarse) { - .c4[data-no-visuals="true"]:after { + .c3[data-no-visuals="true"]:after { content: ""; position: absolute; left: 0; @@ -2870,19 +2716,25 @@ exports[`TextInput renders trailingAction text button with a tooltip 1`] = ` className="c2 TextInput-action" > + diff --git a/src/__tests__/__snapshots__/Tooltip.test.tsx.snap b/src/__tests__/__snapshots__/Tooltip.test.tsx.snap index d461c34404c..c67cc822617 100644 --- a/src/__tests__/__snapshots__/Tooltip.test.tsx.snap +++ b/src/__tests__/__snapshots__/Tooltip.test.tsx.snap @@ -1,60 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Tooltip renders consistently 1`] = ` -.c0 { - position: relative; -} - -.c0::before { - position: absolute; - z-index: 1000001; - display: none; - width: 0px; - height: 0px; - color: #24292f; - pointer-events: none; - content: ''; - border: 6px solid transparent; - opacity: 0; -} - -.c0::after { - position: absolute; - z-index: 1000000; +.c0.c0.c0 { + border: none; + overflow: hidden; + margin: 0; + position: fixed; + background: transparent; + top: 0; + left: 0; display: none; - padding: 0.5em 0.75em; - font: normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; - -webkit-font-smoothing: subpixel-antialiased; - color: #ffffff; - text-align: center; - -webkit-text-decoration: none; - text-decoration: none; - text-shadow: none; - text-transform: none; - -webkit-letter-spacing: normal; - -moz-letter-spacing: normal; - -ms-letter-spacing: normal; - letter-spacing: normal; - word-wrap: break-word; - white-space: pre; - pointer-events: none; - content: attr(aria-label); - background: #24292f; - border-radius: 3px; opacity: 0; -} - -.c0:hover::before, -.c0:active::before, -.c0:focus::before, -.c0:focus-within::before, -.c0:hover::after, -.c0:active::after, -.c0:focus::after, -.c0:focus-within::after { - display: inline-block; - -webkit-text-decoration: none; - text-decoration: none; + padding: 0; + --width: 0; + --height: 0; + --anchor-width: 0; -webkit-animation-name: tooltip-appear; animation-name: tooltip-appear; -webkit-animation-duration: 0.1s; @@ -67,123 +27,113 @@ exports[`Tooltip renders consistently 1`] = ` animation-delay: 0.4s; } -.c0.tooltipped-no-delay:hover::before, -.c0.tooltipped-no-delay:active::before, -.c0.tooltipped-no-delay:focus::before, -.c0.tooltipped-no-delay:focus-within::before, -.c0.tooltipped-no-delay:hover::after, -.c0.tooltipped-no-delay:active::after, -.c0.tooltipped-no-delay:focus::after, -.c0.tooltipped-no-delay:focus-within::after { +.c0.c0.c0.tooltipped-no-delay { -webkit-animation-delay: 0s; animation-delay: 0s; } -.c0.tooltipped-multiline:hover::after, -.c0.tooltipped-multiline:active::after, -.c0.tooltipped-multiline:focus::after, -.c0.tooltipped-multiline:focus-within::after { - display: table-cell; +.c0.c0.c0.\\:open { + display: block; } -.c0.tooltipped-s::after, -.c0.tooltipped-se::after, -.c0.tooltipped-sw::after { - top: 100%; - right: 50%; - margin-top: 6px; +.c0.c0.c0:open { + display: block; +} + +.c0.c0.c0::before { + position: relative; + padding: 0.5em 0.75em; + border-radius: 3px; + font: normal normal 11px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Noto Sans",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji"; + background: #24292f; + color: #ffffff; + content: attr(aria-label); + word-wrap: break-word; + text-align: center; + display: block; } -.c0.tooltipped-s::before, -.c0.tooltipped-se::before, -.c0.tooltipped-sw::before { - top: auto; +.c0.c0.c0::after { + position: absolute; + content: ''; right: 50%; - bottom: -7px; margin-right: -6px; - border-bottom-color: #24292f; + width: 0; + height: 0; + border: 6px solid transparent; } -.c0.tooltipped-se::after { - right: auto; - left: 50%; - margin-left: -16px; +.c0.c0.c0.tooltipped-n, +.c0.c0.c0.tooltipped-ne, +.c0.c0.c0.tooltipped-nw { + padding-bottom: 10px; } -.c0.tooltipped-sw::after { - margin-right: -16px; +.c0.c0.c0.tooltipped-n::after, +.c0.c0.c0.tooltipped-ne::after, +.c0.c0.c0.tooltipped-nw::after { + top: calc(var(--height) - 12px); + border-top-color: #24292f; } -.c0.tooltipped-n::after, -.c0.tooltipped-ne::after, -.c0.tooltipped-nw::after { - right: 50%; - bottom: 100%; - margin-bottom: 6px; +.c0.c0.c0.tooltipped-nw::after { + right: 0.5em; } -.c0.tooltipped-n::before, -.c0.tooltipped-ne::before, -.c0.tooltipped-nw::before { - top: -7px; - right: 50%; - bottom: auto; - margin-right: -6px; - border-top-color: #24292f; +.c0.c0.c0.tooltipped-ne::after { + left: 0.5em; } -.c0.tooltipped-ne::after { - right: auto; - left: 50%; - margin-left: -16px; +.c0.c0.c0.tooltipped-sw { + padding-top: 10px; } -.c0.tooltipped-nw::after { - margin-right: -16px; +.c0.c0.c0.tooltipped-sw::after { + right: 0.5em; + top: 0; + border-bottom-color: #24292f; } -.c0.tooltipped-s::after, -.c0.tooltipped-n::after { - -webkit-transform: translateX(50%); - -ms-transform: translateX(50%); - transform: translateX(50%); +.c0.c0.c0.tooltipped-se { + padding-top: 10px; } -.c0.tooltipped-w::after { - right: 100%; - bottom: 50%; - margin-right: 6px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%); +.c0.c0.c0.tooltipped-se::after { + left: 0.5em; + top: 0; + border-bottom-color: #24292f; } -.c0.tooltipped-w::before { - top: 50%; - bottom: 50%; - left: -7px; - margin-top: -6px; - border-left-color: #24292f; +.c0.c0.c0.tooltipped-s { + padding-top: 10px; +} + +.c0.c0.c0.tooltipped-s::after { + top: 0; + border-bottom-color: #24292f; } -.c0.tooltipped-e::after { - bottom: 50%; - left: 100%; - margin-left: 6px; - -webkit-transform: translateY(50%); - -ms-transform: translateY(50%); - transform: translateY(50%); +.c0.c0.c0.tooltipped-e { + padding-left: 10px; } -.c0.tooltipped-e::before { - top: 50%; - right: -7px; - bottom: 50%; - margin-top: -6px; +.c0.c0.c0.tooltipped-e:after { + top: calc(var(--height) / 2 - 5px); + right: calc(var(--width) - 5px); border-right-color: #24292f; } -.c0.tooltipped-multiline::after { +.c0.c0.c0.tooltipped-w { + padding-right: 10px; +} + +.c0.c0.c0.tooltipped-w::after { + top: calc(var(--height) / 2 - 5px); + right: 4px; + border-left-color: #24292f; +} + +.c0.c0.c0.tooltipped-multiline::before { width: -webkit-max-content; width: -moz-max-content; width: max-content; @@ -193,40 +143,19 @@ exports[`Tooltip renders consistently 1`] = ` border-collapse: separate; } -.c0.tooltipped-multiline.tooltipped-s::after, -.c0.tooltipped-multiline.tooltipped-n::after { - right: auto; - left: 50%; - -webkit-transform: translateX(-50%); - -ms-transform: translateX(-50%); - transform: translateX(-50%); -} - -.c0.tooltipped-multiline.tooltipped-w::after, -.c0.tooltipped-multiline.tooltipped-e::after { - right: 100%; -} - -.c0.tooltipped-align-right-2::after { - right: 0; - margin-right: 0; -} - -.c0.tooltipped-align-right-2::before { - right: 15px; -} - -.c0.tooltipped-align-left-2::after { - left: 0; - margin-left: 0; -} - -.c0.tooltipped-align-left-2::before { - left: 10px; -} - + onBlur={[Function]} + onFocus={[Function]} + onPointerEnter={[Function]} + onPointerLeave={[Function]} + style={ + { + "display": "inline-block", + } + } +> + + `; diff --git a/src/stories/Tooltip.stories.tsx b/src/stories/Tooltip.stories.tsx index 316b0f469b3..6264d5391d0 100644 --- a/src/stories/Tooltip.stories.tsx +++ b/src/stories/Tooltip.stories.tsx @@ -24,8 +24,63 @@ export default { export const IconButtonTooltip = () => ( - + ) + +export const TooltipExample = () => ( + + + + + +) + +export const TooltipWithAncestor = () => ( +
+ + + This is a sticky header + + + + + Second sticky header, Text with a tooltip, within a stacking context + + + + Content goes here, falls behind the sticky headers + + + + Extra padding that pushes the sticky header up +
+) diff --git a/src/utils/testing.tsx b/src/utils/testing.tsx index ef5433002bb..eb6d6735a3b 100644 --- a/src/utils/testing.tsx +++ b/src/utils/testing.tsx @@ -1,6 +1,6 @@ import React from 'react' import {promisify} from 'util' -import renderer from 'react-test-renderer' +import renderer, {ReactTestRendererJSON} from 'react-test-renderer' import {render as HTMLRender} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' import type {Story as StoryType} from '@storybook/react' @@ -67,6 +67,26 @@ export function renderClasses(component: React.ReactElement): string { return className ? className.trim().split(' ') : [] } +/** + * Get the HTML class names rendered by the children of a component instance + * as an array. + * + * ```js + * expect(childRenderClasses(
, 0)) + * .toEqual(['a', 'b']) + * ``` + */ +export function childRenderClasses(component: React.ReactElement, childIndex: number): string { + const {children} = render(component) + if (children !== null) { + const { + props: {className}, + } = children.at(childIndex) as ReactTestRendererJSON + return className ? className.trim().split(' ') : '' + } + return '' +} + /** * Returns true if a node renders with a single class. */ @@ -74,6 +94,13 @@ export function rendersClass(node: React.ReactElement, klass: string): boolean { return renderClasses(node).includes(klass) } +/** + * Returns true if the child of a node renders with a single class. + */ +export function childRendersClass(node: React.ReactElement, klass: string, childIndex: number): boolean { + return childRenderClasses(node, childIndex).includes(klass) +} + export function px(value: number | string): string { return typeof value === 'number' ? `${value}px` : value }