mirror of
https://github.com/rio-labs/rio.git
synced 2026-01-06 05:09:43 -06:00
WIP: AspectRatioContainer
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { AspectRatioContainerComponent } from './components/aspectRatioContainer';
|
||||
import { BuildFailedComponent } from './components/buildFailed';
|
||||
import { ButtonComponent, IconButtonComponent } from './components/buttons';
|
||||
import { CalendarComponent } from './components/calendar';
|
||||
@@ -10,8 +11,10 @@ import { ColorPickerComponent } from './components/colorPicker';
|
||||
import { ColumnComponent, RowComponent } from './components/linearContainers';
|
||||
import { ComponentBase, ComponentState } from './components/componentBase';
|
||||
import { ComponentId } from './dataModels';
|
||||
import { ComponentPickerComponent } from './components/componentPicker';
|
||||
import { ComponentTreeComponent } from './components/componentTree';
|
||||
import { CustomListItemComponent } from './components/customListItem';
|
||||
import { devToolsConnector } from './app';
|
||||
import { DevToolsConnectorComponent } from './components/devToolsConnector';
|
||||
import { DrawerComponent } from './components/drawer';
|
||||
import { DropdownComponent } from './components/dropdown';
|
||||
@@ -19,6 +22,7 @@ import { FlowComponent as FlowContainerComponent } from './components/flowContai
|
||||
import { FundamentalRootComponent } from './components/fundamentalRootComponent';
|
||||
import { GridComponent } from './components/grid';
|
||||
import { HeadingListItemComponent } from './components/headingListItem';
|
||||
import { HighLevelComponent as HighLevelComponent } from './components/highLevelComponent';
|
||||
import { HtmlComponent } from './components/html';
|
||||
import { IconComponent } from './components/icon';
|
||||
import { ImageComponent } from './components/image';
|
||||
@@ -33,7 +37,6 @@ import { MultiLineTextInputComponent } from './components/multiLineTextInput';
|
||||
import { NodeInputComponent } from './components/nodeInput';
|
||||
import { NodeOutputComponent } from './components/nodeOutput';
|
||||
import { OverlayComponent } from './components/overlay';
|
||||
import { HighLevelComponent as HighLevelComponent } from './components/highLevelComponent';
|
||||
import { PlotComponent } from './components/plot';
|
||||
import { PopupComponent } from './components/popup';
|
||||
import { ProgressBarComponent } from './components/progressBar';
|
||||
@@ -41,6 +44,7 @@ import { ProgressCircleComponent } from './components/progressCircle';
|
||||
import { RectangleComponent } from './components/rectangle';
|
||||
import { reprElement, scrollToUrlFragment } from './utils';
|
||||
import { RevealerComponent } from './components/revealer';
|
||||
import { ScrollContainerComponent } from './components/scrollContainer';
|
||||
import { ScrollTargetComponent } from './components/scrollTarget';
|
||||
import { SeparatorComponent } from './components/separator';
|
||||
import { SeparatorListItemComponent } from './components/separatorListItem';
|
||||
@@ -55,11 +59,9 @@ import { TextComponent } from './components/text';
|
||||
import { TextInputComponent } from './components/textInput';
|
||||
import { ThemeContextSwitcherComponent } from './components/themeContextSwitcher';
|
||||
import { TooltipComponent } from './components/tooltip';
|
||||
import { devToolsConnector } from './app';
|
||||
import { ComponentPickerComponent } from './components/componentPicker';
|
||||
import { ScrollContainerComponent } from './components/scrollContainer';
|
||||
|
||||
const COMPONENT_CLASSES = {
|
||||
'AspectRatioContainer-builtin': AspectRatioContainerComponent,
|
||||
'BuildFailed-builtin': BuildFailedComponent,
|
||||
'Button-builtin': ButtonComponent,
|
||||
'Calendar-builtin': CalendarComponent,
|
||||
|
||||
103
frontend/code/components/aspectRatioContainer.ts
Normal file
103
frontend/code/components/aspectRatioContainer.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
import { ComponentBase, ComponentState } from './componentBase';
|
||||
import { ComponentId } from '../dataModels';
|
||||
import { getNaturalSizeInPixels } from '../utils';
|
||||
|
||||
export type AspectRatioContainerState = ComponentState & {
|
||||
_type_: 'AspectRatioContainer-builtin';
|
||||
content?: ComponentId;
|
||||
aspect_ratio: number;
|
||||
};
|
||||
|
||||
export class AspectRatioContainerComponent extends ComponentBase {
|
||||
state: Required<AspectRatioContainerState>;
|
||||
|
||||
private innerElement: HTMLElement;
|
||||
private childContainer: HTMLElement;
|
||||
|
||||
private parentResizeObserver: ResizeObserver;
|
||||
private childResizeObserver: ResizeObserver;
|
||||
|
||||
createElement(): HTMLElement {
|
||||
let element = document.createElement('div');
|
||||
element.classList.add('rio-aspect-ratio-container');
|
||||
|
||||
// Add a second element to apply the child's size to
|
||||
this.innerElement = document.createElement('div');
|
||||
element.appendChild(this.innerElement);
|
||||
|
||||
// Add a child container
|
||||
this.childContainer = document.createElement('div');
|
||||
this.childContainer.classList.add(
|
||||
'rio-aspect-ratio-container-child-container'
|
||||
);
|
||||
this.innerElement.appendChild(this.childContainer);
|
||||
|
||||
// Listen for changes
|
||||
this.parentResizeObserver = new ResizeObserver(
|
||||
this.onParentResize.bind(this)
|
||||
);
|
||||
this.parentResizeObserver.observe(element);
|
||||
|
||||
this.childResizeObserver = new ResizeObserver(
|
||||
this.onParentResize.bind(this)
|
||||
);
|
||||
this.childResizeObserver.observe(this.childContainer);
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
onDestruction(): void {
|
||||
this.parentResizeObserver.disconnect();
|
||||
this.childResizeObserver.disconnect();
|
||||
}
|
||||
|
||||
updateElement(
|
||||
deltaState: AspectRatioContainerState,
|
||||
latentComponents: Set<ComponentBase>
|
||||
): void {
|
||||
super.updateElement(deltaState, latentComponents);
|
||||
|
||||
if (deltaState.content !== undefined) {
|
||||
this.replaceOnlyChild(
|
||||
latentComponents,
|
||||
deltaState.content,
|
||||
this.childContainer
|
||||
);
|
||||
}
|
||||
|
||||
if (deltaState.aspect_ratio !== undefined) {
|
||||
this.childContainer.style.aspectRatio =
|
||||
deltaState.aspect_ratio.toString();
|
||||
}
|
||||
}
|
||||
|
||||
onParentResize(): void {
|
||||
// Get the parent's and child's dimensions
|
||||
let parentRect = this.element.getBoundingClientRect();
|
||||
let parentAspectRatio = parentRect.width / parentRect.height;
|
||||
|
||||
// Update the child's dimensions
|
||||
if (parentAspectRatio > this.state.aspect_ratio) {
|
||||
this.childContainer.style.width = 'auto';
|
||||
this.childContainer.style.height = '100%';
|
||||
|
||||
this.childContainer.style.left = '50%';
|
||||
this.childContainer.style.top = '0';
|
||||
this.childContainer.style.transform = 'translateX(-50%)';
|
||||
} else {
|
||||
this.childContainer.style.width = '100%';
|
||||
this.childContainer.style.height = 'auto';
|
||||
|
||||
this.childContainer.style.left = '0';
|
||||
this.childContainer.style.top = '50%';
|
||||
this.childContainer.style.transform = 'translateY(-50%)';
|
||||
}
|
||||
}
|
||||
|
||||
onChildResize(): void {
|
||||
let childElement = this.innerElement.firstElementChild as HTMLElement;
|
||||
let childNaturalSize = getNaturalSizeInPixels(childElement);
|
||||
this.innerElement.style.minWidth = `${childNaturalSize[0]}px`;
|
||||
this.innerElement.style.minHeight = `${childNaturalSize[1]}px`;
|
||||
}
|
||||
}
|
||||
@@ -3628,3 +3628,13 @@ html.picking-component * {
|
||||
.rio-checkbox.is-on .rio-checkbox-check {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
// Aspect Ratio Container
|
||||
.rio-aspect-ratio-container {
|
||||
@include single-container();
|
||||
|
||||
& > div > .rio-aspect-ratio-container-child-container {
|
||||
position: absolute;
|
||||
@include single-container();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from .aspect_ratio_container import *
|
||||
from .auto_form import *
|
||||
from .banner import *
|
||||
from .button import *
|
||||
|
||||
19
rio/components/aspect_ratio_container.py
Normal file
19
rio/components/aspect_ratio_container.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import rio
|
||||
|
||||
from .fundamental_component import FundamentalComponent
|
||||
|
||||
__all__ = [
|
||||
"AspectRatioContainer",
|
||||
]
|
||||
|
||||
|
||||
class AspectRatioContainer(FundamentalComponent):
|
||||
# TODO
|
||||
|
||||
content: rio.Component
|
||||
aspect_ratio: float
|
||||
|
||||
|
||||
AspectRatioContainer._unique_id = "AspectRatioContainer-builtin"
|
||||
Reference in New Issue
Block a user