mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
overflow-anchor to hold view to bottom of scrollable action output (#19452)
This commit is contained in:
3
.changelog/19452.txt
Normal file
3
.changelog/19452.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
```release-note:improvement
|
||||
ui: when an Action has long output, anchor to the latest messages
|
||||
```
|
||||
@@ -71,7 +71,12 @@
|
||||
<code><pre>Error: {{this.instance.error}}</pre></code>
|
||||
{{/if}}
|
||||
{{#if this.instance.messages.length}}
|
||||
<code><pre>{{this.instance.messages}}</pre></code>
|
||||
<code tabindex="0">
|
||||
<pre {{did-update this.anchorToBottom this.instance.messages}}>
|
||||
{{this.instance.messages}}
|
||||
</pre>
|
||||
<div class="anchor" />
|
||||
</code>
|
||||
{{else}}
|
||||
{{#if (eq this.instance.state "complete")}}
|
||||
<p class="no-messages">Action completed with no output</p>
|
||||
|
||||
@@ -48,4 +48,30 @@ export default class ActionCardComponent extends Component {
|
||||
// Either the passed instance, or the peer-selected instance
|
||||
return this.selectedPeer || this.args.instance;
|
||||
}
|
||||
|
||||
@tracked hasBeenAnchored = false;
|
||||
|
||||
/**
|
||||
* Runs from the action-card template whenever instance.messages updates,
|
||||
* and serves to keep the user's view anchored to the bottom of the messages.
|
||||
* This uses a hidden element and the overflow-anchor css attribute, which
|
||||
* keeps the element visible within the scrollable <code> block parent.
|
||||
* A trick here is that, if the user scrolls up from the bottom of the block,
|
||||
* we don't want to force them down to the bottom again on update, but we do
|
||||
* want to keep them there by default (so they have the latest output).
|
||||
* The hasBeenAnchored flag is used to track this state, and we do a little
|
||||
* trick when the messages get long enough to cause a scroll to start the
|
||||
* anchoring process here.
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
*/
|
||||
@action anchorToBottom(element) {
|
||||
if (this.hasBeenAnchored) return;
|
||||
const parentHeight = element.parentElement.clientHeight;
|
||||
const elementHeight = element.clientHeight;
|
||||
if (elementHeight > parentHeight) {
|
||||
this.hasBeenAnchored = true;
|
||||
element.parentElement.scroll(0, elementHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,14 +117,30 @@
|
||||
}
|
||||
|
||||
.messages {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
code > pre {
|
||||
height: 200px;
|
||||
code {
|
||||
background-color: #0a0a0a;
|
||||
color: whitesmoke;
|
||||
display: block;
|
||||
overflow: auto;
|
||||
height: 200px;
|
||||
border-radius: 6px;
|
||||
resize: vertical;
|
||||
pre {
|
||||
background-color: transparent;
|
||||
color: unset;
|
||||
overflow-anchor: none;
|
||||
min-height: 100%;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.anchor {
|
||||
overflow-anchor: auto;
|
||||
height: 1px;
|
||||
margin-top: -1px;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user