From e0c663c20dcab44fba6046b0783fea7803f68ea3 Mon Sep 17 00:00:00 2001 From: Joe <33972521+hnb-ku@users.noreply.github.com> Date: Tue, 19 Apr 2022 21:13:54 +0800 Subject: [PATCH] UX: Improves select-kit body placement when vertical space is short (#16504) 1. When the select-kit body is rendered, it defaults to being displayed under the triggering select-kit header, unless... there isn't enough space between the bottom of the select-kit header and the bottom of the viewport & there's enough space on top of the select-kit header, and in that case, we render it on top. 2. We give it a bit of padding on top, so it never renders below the header on the Z-axis. https://github.com/discourse/discourse/blob/14778ba52e6f9281f58f74dbf4090c53e971a966/app/assets/javascripts/select-kit/addon/components/select-kit.js#L877-L884 3. If there isn't enough space between the bottom of the viewport and the bottom of the select-kit header, and there isn't enough space between its top and the bottom of `d-header`, it renders at the bottom of the select-kit header. In theory, number 3 above rarely ever happens. However, it can occur in the case of the user preferences page in combination with a large select-kit body (many categories). The select-kit body then renders below the trigging select-kit header, but it's cut off. Users won't be able to see the entire select-kit body. Here's an example https://d11a6trkgmumsb.cloudfront.net/original/4X/a/7/1/a719734d9227c9c9e0ffee5718284a70f8eb1c89.mp4 This PR adds a "prevent overflow" modifier to Popper. What it does is that it handles the case above. If there's not enough space below the select-kit header or above it, render the select-kit body below the select-kit header BUT... anchor it to the bottom of the viewport. Here's what that looks like https://d11a6trkgmumsb.cloudfront.net/original/4X/3/2/c/32cd1639bbbc499c89676b587f7152ac2e92ae48.mp4 After this fix, even very large select-kit bodies will always be on the screen. Please note that this PR has no impact on either number 1 or number 2 above, and those will continue to function as they currently do. The only downside here is that the select-kit body might cover the select-kit header if it needs to be anchored at the bottom of the viewport, and it's very large. However, between that and not being able to see all the options, I think it's a fair compromise. There's only so much space in the viewport. This PR ignores mobile because we have a different placement strategy. We use `position: absolute`... so, users can scroll the viewport if needed. --- .../javascripts/select-kit/addon/components/select-kit.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/assets/javascripts/select-kit/addon/components/select-kit.js b/app/assets/javascripts/select-kit/addon/components/select-kit.js index 3de48b094c3..ff6308e1dca 100644 --- a/app/assets/javascripts/select-kit/addon/components/select-kit.js +++ b/app/assets/javascripts/select-kit/addon/components/select-kit.js @@ -885,6 +885,12 @@ export default Component.extend( }, }, }, + { + name: "preventOverflow", + options: { + altAxis: !this?.site?.mobileView, + }, + }, { name: "offset", options: {