mirror of
https://github.com/rio-labs/rio.git
synced 2026-05-01 16:39:29 -05:00
popup progress
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
} from "../componentManagement";
|
||||
import { ComponentId } from "../dataModels";
|
||||
import { markEventAsHandled } from "../eventHandling";
|
||||
import { PopupManager, positionFullscreen } from "../popupManager";
|
||||
import { callRemoteMethodDiscardResponse } from "../rpc";
|
||||
import { commitCss } from "../utils";
|
||||
import { ComponentBase, ComponentState } from "./componentBase";
|
||||
@@ -19,55 +20,26 @@ export type DialogContainerState = ComponentState & {
|
||||
export class DialogContainerComponent extends ComponentBase {
|
||||
declare state: Required<DialogContainerState>;
|
||||
|
||||
private contentContainer: HTMLElement;
|
||||
|
||||
// Dialogs are displayed via a popup manager. While this isn't strictly
|
||||
// necessary, this allows sharing the code for whether the dialog is modal,
|
||||
// user-closable and general styling.
|
||||
private popupManager: PopupManager;
|
||||
|
||||
createElement(): HTMLElement {
|
||||
// Create the element
|
||||
// Create the HTML elements
|
||||
let element = document.createElement("div");
|
||||
element.classList.add("rio-dialog-container", "rio-switcheroo-neutral");
|
||||
element.classList.add("rio-dialog-container");
|
||||
|
||||
// Since dialog containers aren't part of the component tree, they're
|
||||
// themselves responsible for adding themselves to the DOM.
|
||||
document.body.appendChild(element);
|
||||
this.contentContainer = document.createElement("div");
|
||||
|
||||
// Animate the element
|
||||
requestAnimationFrame(() => {
|
||||
commitCss(element);
|
||||
element.classList.add("rio-dialog-container-enter");
|
||||
});
|
||||
|
||||
// Listen for outside clicks
|
||||
element.addEventListener("click", (event) => {
|
||||
markEventAsHandled(event);
|
||||
|
||||
// Don't close the dialog if the click was inside the dialog. This
|
||||
// is a bit tricky, because of various cases:
|
||||
//
|
||||
// - The click was handled by a component inside of the dialog (e.g.
|
||||
// a Button). This is simple, since the event will never reach the
|
||||
// dialog container.
|
||||
// - The click was onto a component in the dialog, but not handled.
|
||||
// (Think a `rio.Card`). This must be detected and the dialog NOT
|
||||
// closed.
|
||||
// - The click was technically into a component, but that component
|
||||
// doesn't accept clicks. (Think the spacing of a `rio.Row`.)
|
||||
// Since no component was technically clicked, the dialog should
|
||||
// close.
|
||||
if (event.target !== element) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the dialog user-closable?
|
||||
if (!this.state.is_user_closable) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Yes! Close it. First, inform the server.
|
||||
callRemoteMethodDiscardResponse("dialogClosed", {
|
||||
dialogRootComponentId: this.id,
|
||||
});
|
||||
|
||||
// Clean up
|
||||
recursivelyDeleteComponent(this);
|
||||
});
|
||||
// Set up the popup manager
|
||||
this.popupManager = new PopupManager(
|
||||
element,
|
||||
this.contentContainer,
|
||||
positionFullscreen
|
||||
);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@@ -58,14 +58,14 @@ export function positionDropdown(
|
||||
|
||||
content.style.left = "0";
|
||||
content.style.top = "0";
|
||||
content.style.width = `${windowWidth}px`;
|
||||
content.style.height = `${windowHeight}px`;
|
||||
content.style.width = "100vw";
|
||||
content.style.height = "100vh";
|
||||
|
||||
anchor.classList.add("rio-dropdown-popup-mobile-fullscreen");
|
||||
content.classList.add("rio-dropdown-popup-mobile-fullscreen");
|
||||
return;
|
||||
}
|
||||
|
||||
anchor.classList.remove("rio-dropdown-popup-mobile-fullscreen");
|
||||
content.classList.remove("rio-dropdown-popup-mobile-fullscreen");
|
||||
|
||||
// TODO
|
||||
//
|
||||
@@ -77,7 +77,7 @@ export function positionDropdown(
|
||||
content.style.left = `${anchorRect.left}px`;
|
||||
content.style.top = `${DESKTOP_WINDOW_MARGIN}px`;
|
||||
content.style.width = `${anchorRect.width}px`;
|
||||
content.style.height = `${windowHeight - 2 * DESKTOP_WINDOW_MARGIN}px`;
|
||||
content.style.height = `calc(100vh - ${2 * DESKTOP_WINDOW_MARGIN}px)`;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,10 +88,9 @@ export function positionDropdown(
|
||||
) {
|
||||
content.style.left = `${anchorRect.left}px`;
|
||||
content.style.top = `${anchorRect.bottom}px`;
|
||||
content.style.width = `${anchorRect.width}px`;
|
||||
content.style.height = `${contentHeight}px`;
|
||||
content.style.width = `max(min-content, ${anchorRect.width}px)`;
|
||||
content.style.height = `min-content`;
|
||||
content.style.maxHeight = `${contentHeight}px`;
|
||||
content.style.overflowY = "hidden";
|
||||
return;
|
||||
}
|
||||
// Popup fits above the dropdown
|
||||
@@ -106,7 +105,6 @@ export function positionDropdown(
|
||||
content.style.width = `${anchorRect.width}px`;
|
||||
content.style.height = `${contentHeight}px`;
|
||||
content.style.maxHeight = `${contentHeight}px`;
|
||||
content.style.overflowY = "hidden";
|
||||
}
|
||||
// Popup doesn't fit above or below the dropdown. Center it as much
|
||||
// as possible
|
||||
@@ -123,7 +121,7 @@ export function positionDropdown(
|
||||
content.style.width = `${anchorRect.width}px`;
|
||||
content.style.height = `${contentHeight}px`;
|
||||
content.style.maxHeight = `${contentHeight}px`;
|
||||
content.style.overflowY = "hidden";
|
||||
content.style.overflowY = "auto";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -196,14 +194,6 @@ export function positionOnSide({
|
||||
content.style.top = `${contentTop}px`;
|
||||
content.style.width = `${contentWidth}px`;
|
||||
content.style.height = `${contentHeight}px`;
|
||||
|
||||
// return {
|
||||
// leftPx: contentLeft,
|
||||
// topPx: contentTop,
|
||||
// widthPx: contentWidth,
|
||||
// heightPx: contentHeight,
|
||||
// additionalCss: {},
|
||||
// };
|
||||
}
|
||||
|
||||
export function makePositionLeft(
|
||||
|
||||
+1
-33
@@ -3619,6 +3619,7 @@ html.picking-component * {
|
||||
|
||||
.rio-popup-manager-animation-slide-from-top {
|
||||
transition: max-height 0.2s ease-in-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rio-popup-manager-shade:not(.rio-popup-manager-open)
|
||||
@@ -3874,39 +3875,6 @@ html.picking-component * {
|
||||
@include single-container(); // FIXME: Should we do this?
|
||||
}
|
||||
|
||||
// Dialogs
|
||||
.rio-dialog-container {
|
||||
pointer-events: none;
|
||||
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: $z-index-popup;
|
||||
|
||||
background-color: transparent;
|
||||
opacity: 0;
|
||||
|
||||
// Theses durations are also referenced in code!
|
||||
transition: opacity 0.2s ease-in-out, background-color 0.5s ease-in-out;
|
||||
|
||||
& > * {
|
||||
transform: translateY(-2rem);
|
||||
transition: transform 0.2s $transition-timing-overshoot;
|
||||
}
|
||||
|
||||
@include single-container();
|
||||
}
|
||||
|
||||
.rio-dialog-container-enter {
|
||||
background-color: $modal-shade;
|
||||
opacity: 1;
|
||||
|
||||
& > * {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Upload Area
|
||||
.rio-file-picker-area {
|
||||
|
||||
Reference in New Issue
Block a user