mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
Merge pull request #55 from prymitive/animate-navbar
feat(ui): animate navbar show/hide
This commit is contained in:
@@ -1,14 +1,8 @@
|
||||
.components-animation-fade-appear {
|
||||
opacity: 0.01;
|
||||
}
|
||||
.components-animation-fade-appear-active {
|
||||
opacity: 1;
|
||||
transition: opacity 0.15s ease-in;
|
||||
}
|
||||
|
||||
.components-animation-fade-appear,
|
||||
.components-animation-fade-enter {
|
||||
opacity: 0.01;
|
||||
}
|
||||
.components-animation-fade-appear-active,
|
||||
.components-animation-fade-enter-active {
|
||||
opacity: 1;
|
||||
transition: opacity 0.15s ease-in;
|
||||
@@ -19,5 +13,5 @@
|
||||
}
|
||||
.components-animation-fade-exit-active {
|
||||
opacity: 0.01;
|
||||
transition: opacity 0.15s ease-in;
|
||||
transition: opacity 0.15s ease-out;
|
||||
}
|
||||
|
||||
@@ -11,13 +11,17 @@ import IdleTimer from "react-idle-timer";
|
||||
import { AlertStore } from "Stores/AlertStore";
|
||||
import { Settings } from "Stores/Settings";
|
||||
import { SilenceFormStore } from "Stores/SilenceFormStore";
|
||||
import { FetchIndicator } from "./FetchIndicator";
|
||||
import { FilterInput } from "./FilterInput";
|
||||
import { DropdownSlide } from "Components/Animations/DropdownSlide";
|
||||
import { MainModal } from "Components/MainModal";
|
||||
import { SilenceModal } from "Components/SilenceModal";
|
||||
import { FetchIndicator } from "./FetchIndicator";
|
||||
import { FilterInput } from "./FilterInput";
|
||||
|
||||
import "./index.css";
|
||||
|
||||
const DesktopIdleTimeout = 1000 * 60 * 3;
|
||||
const MobileIdleTimeout = 1000 * 5;
|
||||
|
||||
const NavbarOnResize = function(width, height) {
|
||||
document.body.style["padding-top"] = `${height + 4}px`;
|
||||
};
|
||||
@@ -46,6 +50,10 @@ const NavBar = observer(
|
||||
}
|
||||
);
|
||||
|
||||
onHide = () => {
|
||||
NavbarOnResize(0, 0);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { alertStore, settingsStore, silenceFormStore } = this.props;
|
||||
|
||||
@@ -61,36 +69,41 @@ const NavBar = observer(
|
||||
<IdleTimer
|
||||
onActive={this.activityStatus.setActive}
|
||||
onIdle={this.activityStatus.setIdle}
|
||||
timeout={1000 * 60 * 3}
|
||||
timeout={
|
||||
window.innerWidth >= 768 ? DesktopIdleTimeout : MobileIdleTimeout
|
||||
}
|
||||
>
|
||||
<div className="container">
|
||||
<nav
|
||||
className={`navbar fixed-top navbar-expand navbar-dark p-1 bg-primary-transparent ${
|
||||
this.activityStatus.idle ? "d-none" : "d-inline-block"
|
||||
}`}
|
||||
>
|
||||
<ReactResizeDetector handleHeight onResize={NavbarOnResize} />
|
||||
<span className="navbar-brand my-0 mx-2 h1 d-none d-sm-block float-left">
|
||||
{alertStore.info.totalAlerts}
|
||||
<FetchIndicator alertStore={alertStore} />
|
||||
</span>
|
||||
<ul className={`navbar-nav float-right d-flex ${flexClass}`}>
|
||||
<SilenceModal
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
<MainModal
|
||||
<DropdownSlide
|
||||
in={!this.activityStatus.idle}
|
||||
appear={false}
|
||||
onExited={this.onHide}
|
||||
unmountOnExit
|
||||
>
|
||||
<div className="container">
|
||||
<nav className="navbar fixed-top navbar-expand navbar-dark p-1 bg-primary-transparent d-inline-block">
|
||||
<ReactResizeDetector handleHeight onResize={NavbarOnResize} />
|
||||
<span className="navbar-brand my-0 mx-2 h1 d-none d-sm-block float-left">
|
||||
{alertStore.info.totalAlerts}
|
||||
<FetchIndicator alertStore={alertStore} />
|
||||
</span>
|
||||
<ul className={`navbar-nav float-right d-flex ${flexClass}`}>
|
||||
<SilenceModal
|
||||
alertStore={alertStore}
|
||||
silenceFormStore={silenceFormStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
<MainModal
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
</ul>
|
||||
<FilterInput
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
</ul>
|
||||
<FilterInput
|
||||
alertStore={alertStore}
|
||||
settingsStore={settingsStore}
|
||||
/>
|
||||
</nav>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</DropdownSlide>
|
||||
</IdleTimer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -112,26 +112,39 @@ describe("<IdleTimer />", () => {
|
||||
|
||||
it("hides navbar after 4 minutes", () => {
|
||||
const tree = MountedNavbar();
|
||||
expect(tree.find(".navbar").hasClass("d-inline-block")).toBe(true);
|
||||
expect(tree.find(".navbar").hasClass("d-none")).toBe(false);
|
||||
expect(tree.find(".navbar")).toHaveLength(1);
|
||||
|
||||
jest.runTimersToTime(1000 * 60 * 4);
|
||||
tree.update();
|
||||
expect(tree.find(".navbar").hasClass("d-inline-block")).toBe(false);
|
||||
expect(tree.find(".navbar").hasClass("d-none")).toBe(true);
|
||||
expect(tree.find(".navbar")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("hidden navbar shows up again after activity", () => {
|
||||
const tree = MountedNavbar();
|
||||
const instance = tree.instance();
|
||||
|
||||
instance.activityStatus.idle = true;
|
||||
jest.runOnlyPendingTimers();
|
||||
tree.update();
|
||||
expect(tree.find(".navbar").hasClass("d-inline-block")).toBe(false);
|
||||
expect(tree.find(".navbar").hasClass("d-none")).toBe(true);
|
||||
expect(tree.find(".navbar")).toHaveLength(0);
|
||||
|
||||
instance.activityStatus.setActive();
|
||||
jest.runOnlyPendingTimers();
|
||||
tree.update();
|
||||
expect(tree.find(".navbar").hasClass("d-inline-block")).toBe(true);
|
||||
expect(tree.find(".navbar").hasClass("d-none")).toBe(false);
|
||||
expect(tree.find(".navbar")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("body padding-top is 4px when navbar is hidden", () => {
|
||||
const tree = MountedNavbar();
|
||||
const instance = tree.instance();
|
||||
|
||||
instance.activityStatus.setIdle();
|
||||
jest.runOnlyPendingTimers();
|
||||
tree.update();
|
||||
expect(
|
||||
window
|
||||
.getComputedStyle(document.body, null)
|
||||
.getPropertyValue("padding-top")
|
||||
).toBe("4px");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user