mirror of
https://github.com/rio-labs/rio.git
synced 2026-01-06 05:09:43 -06:00
improved dropdown on mobile
This commit is contained in:
@@ -109,18 +109,37 @@ export class DropdownComponent extends ComponentBase {
|
||||
// Position & Animate
|
||||
let anchorRect = this.element.getBoundingClientRect();
|
||||
let popupHeight = this.popupElement.scrollHeight;
|
||||
let windowWidth = window.innerWidth - 1; // innerWidth is rounded
|
||||
let windowHeight = window.innerHeight - 1; // innerHeight is rounded
|
||||
|
||||
const WINDOW_MARGIN = 0.5 * pixelsPerRem;
|
||||
const DESKTOP_WINDOW_MARGIN = 0.5 * pixelsPerRem;
|
||||
const MOBILE_WINDOW_MARGIN = 2 * pixelsPerRem;
|
||||
const GAP_IF_ENTIRELY_ABOVE = 0.5 * pixelsPerRem;
|
||||
|
||||
// On small screens, such as phones, go fullscreen
|
||||
if (false) {
|
||||
//
|
||||
// TODO: Adjust these thresholds. Maybe have a global variable which
|
||||
// keeps track of whether we're on mobile?
|
||||
console.debug(
|
||||
`Width: ${windowWidth / pixelsPerRem}rem Height: ${
|
||||
windowHeight / pixelsPerRem
|
||||
}rem`
|
||||
);
|
||||
if (
|
||||
windowWidth < 60 * pixelsPerRem ||
|
||||
windowHeight < 40 * pixelsPerRem
|
||||
) {
|
||||
// Make sure mobile browsers don't display a keyboard
|
||||
this.inputBox.inputElement.readOnly = true;
|
||||
|
||||
// Style the popup
|
||||
this.popupElement.classList.add('rio-dropdown-popup-fullscreen');
|
||||
|
||||
if (popupHeight >= windowHeight - 2 * WINDOW_MARGIN) {
|
||||
if (popupHeight >= windowHeight - 2 * MOBILE_WINDOW_MARGIN) {
|
||||
return {
|
||||
'max-height': `${windowHeight - 2 * WINDOW_MARGIN}px`,
|
||||
'max-height': `${
|
||||
windowHeight - 2 * MOBILE_WINDOW_MARGIN
|
||||
}px`,
|
||||
'overflow-y': 'scroll',
|
||||
};
|
||||
} else {
|
||||
@@ -131,23 +150,27 @@ export class DropdownComponent extends ComponentBase {
|
||||
}
|
||||
}
|
||||
|
||||
this.inputBox.inputElement.readOnly = false;
|
||||
this.popupElement.classList.remove('rio-dropdown-popup-fullscreen');
|
||||
|
||||
// Popup is larger than the window. Give it all the space that's
|
||||
// available.
|
||||
if (popupHeight >= windowHeight - 2 * WINDOW_MARGIN) {
|
||||
if (popupHeight >= windowHeight - 2 * DESKTOP_WINDOW_MARGIN) {
|
||||
return {
|
||||
left: `${anchorRect.left}px`,
|
||||
top: `${WINDOW_MARGIN}px`,
|
||||
top: `${DESKTOP_WINDOW_MARGIN}px`,
|
||||
width: `${anchorRect.width}px`,
|
||||
'max-height': `${windowHeight - 2 * WINDOW_MARGIN}px`,
|
||||
'max-height': `${windowHeight - 2 * DESKTOP_WINDOW_MARGIN}px`,
|
||||
'overflow-y': 'scroll',
|
||||
'border-radius': 'var(--rio-global-corner-radius-small)',
|
||||
};
|
||||
}
|
||||
|
||||
// Popup fits below the dropdown
|
||||
if (anchorRect.bottom + popupHeight + WINDOW_MARGIN <= windowHeight) {
|
||||
if (
|
||||
anchorRect.bottom + popupHeight + DESKTOP_WINDOW_MARGIN <=
|
||||
windowHeight
|
||||
) {
|
||||
return {
|
||||
left: `${anchorRect.left}px`,
|
||||
top: `${anchorRect.bottom}px`,
|
||||
@@ -159,7 +182,7 @@ export class DropdownComponent extends ComponentBase {
|
||||
// Popup fits above the dropdown
|
||||
else if (
|
||||
anchorRect.top - popupHeight >=
|
||||
GAP_IF_ENTIRELY_ABOVE + WINDOW_MARGIN
|
||||
GAP_IF_ENTIRELY_ABOVE + DESKTOP_WINDOW_MARGIN
|
||||
) {
|
||||
return {
|
||||
left: `${anchorRect.left}px`,
|
||||
@@ -177,10 +200,13 @@ export class DropdownComponent extends ComponentBase {
|
||||
else {
|
||||
console.debug('TRIG');
|
||||
let top = anchorRect.top + anchorRect.height / 2 - popupHeight / 2;
|
||||
if (top < WINDOW_MARGIN) {
|
||||
top = WINDOW_MARGIN;
|
||||
} else if (top + popupHeight + WINDOW_MARGIN > windowHeight) {
|
||||
top = windowHeight - popupHeight - WINDOW_MARGIN;
|
||||
if (top < DESKTOP_WINDOW_MARGIN) {
|
||||
top = DESKTOP_WINDOW_MARGIN;
|
||||
} else if (
|
||||
top + popupHeight + DESKTOP_WINDOW_MARGIN >
|
||||
windowHeight
|
||||
) {
|
||||
top = windowHeight - popupHeight - DESKTOP_WINDOW_MARGIN;
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -63,12 +63,13 @@ export class FundamentalRootComponent extends ComponentBase {
|
||||
'.rio-dev-tools-container'
|
||||
) as HTMLElement;
|
||||
|
||||
// Notify the backend whenever the "window" size changes (it's not
|
||||
// really the whole window because the dev tools sidebar is excluded)
|
||||
// Watch for "window" size changes (it's not really the whole window
|
||||
// because the dev tools sidebar is excluded)
|
||||
let outerUserRootContainer = element.querySelector(
|
||||
'.rio-user-root-container-outer'
|
||||
) as HTMLElement;
|
||||
new ResizeObserver(() => {
|
||||
// Notify the backend of the new size
|
||||
let rect = outerUserRootContainer.getBoundingClientRect();
|
||||
notifyBackendOfWindowSizeChange.call(
|
||||
rect.width / pixelsPerRem,
|
||||
|
||||
@@ -956,7 +956,9 @@ $rio-input-box-small-label-spacing-top: 0.5rem;
|
||||
}
|
||||
|
||||
.rio-dropdown-popup {
|
||||
transition: max-height 0.2s ease-in-out;
|
||||
transition:
|
||||
max-height 0.2s ease-in-out,
|
||||
box-shadow 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.rio-dropdown-popup:not(.rio-popup-manager-open) {
|
||||
@@ -964,26 +966,25 @@ $rio-input-box-small-label-spacing-top: 0.5rem;
|
||||
}
|
||||
|
||||
.rio-dropdown-popup-fullscreen {
|
||||
position: absolute;
|
||||
z-index: $z-index-popup;
|
||||
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
min-width: 12rem;
|
||||
min-width: 15rem;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
background-color: var(--rio-global-neutral-bg);
|
||||
border-radius: var(--rio-global-corner-radius-medium);
|
||||
|
||||
// FIXME: This should really shade the entire screen rather than just be a
|
||||
// shadow. However, after spending hours on trying - and failing - to get
|
||||
// this to work, I've decided a shadow will do.
|
||||
box-shadow: 0 0 0 transparent;
|
||||
}
|
||||
|
||||
.rio-dropdown-popup-fullscreen::before {
|
||||
content: '';
|
||||
pointer-events: none;
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
// background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: $z-index-popup - 1;
|
||||
.rio-dropdown-popup-fullscreen.rio-popup-manager-open {
|
||||
box-shadow: 0 0 3rem var(--rio-global-shadow-color);
|
||||
}
|
||||
|
||||
.rio-dropdown-arrow {
|
||||
|
||||
Reference in New Issue
Block a user