mirror of
https://github.com/zadam/trilium.git
synced 2025-12-12 10:24:23 +01:00
feat(ribbon): basic implementation for scroll pinning
This commit is contained in:
parent
6b059a9a75
commit
0805e077a1
18
apps/client/src/widgets/containers/content_header.css
Normal file
18
apps/client/src/widgets/containers/content_header.css
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
.content-header-widget {
|
||||||
|
position: relative;
|
||||||
|
transition: position 0.3s ease, box-shadow 0.3s ease, z-index 0.3s ease;
|
||||||
|
z-index: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-header-widget.floating {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 11;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
background-color: var(--main-background-color, #fff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure content inside doesn't get affected by the floating state */
|
||||||
|
.content-header-widget > * {
|
||||||
|
transition: inherit;
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ import { EventData } from "../../components/app_context";
|
|||||||
import BasicWidget from "../basic_widget";
|
import BasicWidget from "../basic_widget";
|
||||||
import Container from "./container";
|
import Container from "./container";
|
||||||
import NoteContext from "../../components/note_context";
|
import NoteContext from "../../components/note_context";
|
||||||
|
import "./content_header.css";
|
||||||
|
|
||||||
export default class ContentHeader extends Container<BasicWidget> {
|
export default class ContentHeader extends Container<BasicWidget> {
|
||||||
|
|
||||||
@ -11,6 +12,9 @@ export default class ContentHeader extends Container<BasicWidget> {
|
|||||||
resizeObserver: ResizeObserver;
|
resizeObserver: ResizeObserver;
|
||||||
currentHeight: number = 0;
|
currentHeight: number = 0;
|
||||||
currentSafeMargin: number = NaN;
|
currentSafeMargin: number = NaN;
|
||||||
|
previousScrollTop: number = 0;
|
||||||
|
isFloating: boolean = false;
|
||||||
|
scrollThreshold: number = 10; // pixels before triggering float
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -35,7 +39,36 @@ export default class ContentHeader extends Container<BasicWidget> {
|
|||||||
this.thisElement = this.$widget.get(0)!;
|
this.thisElement = this.$widget.get(0)!;
|
||||||
|
|
||||||
this.resizeObserver.observe(this.thisElement);
|
this.resizeObserver.observe(this.thisElement);
|
||||||
this.parentElement.addEventListener("scroll", this.updateSafeMargin.bind(this));
|
this.parentElement.addEventListener("scroll", this.updateScrollState.bind(this), { passive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
updateScrollState() {
|
||||||
|
const currentScrollTop = this.parentElement!.scrollTop;
|
||||||
|
const isScrollingUp = currentScrollTop < this.previousScrollTop;
|
||||||
|
const hasMovedEnough = Math.abs(currentScrollTop - this.previousScrollTop) > this.scrollThreshold;
|
||||||
|
|
||||||
|
if (hasMovedEnough) {
|
||||||
|
this.setFloating(isScrollingUp);
|
||||||
|
this.previousScrollTop = currentScrollTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateSafeMargin();
|
||||||
|
}
|
||||||
|
|
||||||
|
setFloating(shouldFloat: boolean) {
|
||||||
|
if (shouldFloat !== this.isFloating) {
|
||||||
|
this.isFloating = shouldFloat;
|
||||||
|
|
||||||
|
if (shouldFloat) {
|
||||||
|
this.$widget.addClass("floating");
|
||||||
|
// Set CSS variable so ribbon can position itself below the floating header
|
||||||
|
this.parentElement!.style.setProperty("--content-header-height", `${this.currentHeight}px`);
|
||||||
|
} else {
|
||||||
|
this.$widget.removeClass("floating");
|
||||||
|
// Reset CSS variable when header is not floating
|
||||||
|
this.parentElement!.style.removeProperty("--content-header-height");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSafeMargin() {
|
updateSafeMargin() {
|
||||||
|
|||||||
@ -1,5 +1,15 @@
|
|||||||
.ribbon-container {
|
.ribbon-container {
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
|
position: relative;
|
||||||
|
transition: position 0.3s ease, z-index 0.3s ease, top 0.3s ease;
|
||||||
|
z-index: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When content header is floating, ribbon sticks below it */
|
||||||
|
.scrolling-container:has(.content-header-widget.floating) .ribbon-container {
|
||||||
|
position: sticky;
|
||||||
|
top: var(--content-header-height, 100px);
|
||||||
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ribbon-top-row {
|
.ribbon-top-row {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user