Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Keep the scroll position of the preview pane in sync with what's being edited #1466

Open
papandreou opened this issue Jun 25, 2018 · 6 comments

Comments

@papandreou
Copy link
Contributor

- Do you want to request a feature or report a bug?

feature

- What is the current behavior?

When you're authoring content, the preview pane either has to be scrolled separately or be in the "autoscroll" mode, which currently seems to mean "scroll the preview pane as many percent down as the content pane". When many individually collapsed and expanded editor components are involved, the autoscroll strategy most often scrolls to a place that's unrelated to what's being edited, so the manual scroll mode is the only usable option.

I'd share screenshots of my current setup, but I'm not at liberty to, unfortunately.

- What is the expected behavior?

That the preview pane automatically scrolls into view the preview of the content or component that's actually being edited.

I'm unsure about whether this is already possible without direct core support by using off-the-shelf react components and existing netlify-cms hooks. Pointers would be appreciated :)

@erquhart
Copy link
Contributor

This is a known issue, definitely open to someone digging in. The current behavior is extremely simplistic, which is why we provided the toggle for turning scroll syncing off, as it can be a challenge to work with for large or complex documents.

I've yet to find a library that would handle this well for our case. The complexity is in the variable ratio between the height of a control and the height of it's preview. For example, a very small image control may be tied to a 2000px height image in the preview pane. Likewise, a large, multi-field control widget may be tied to a very small section of text in the preview pane.

I'll briefly give a naive description of what I'd expect to work:

  • use the vertical center of the control pane to determine where to scroll the preview pane
  • determine which control component is on center, and the percent of it's height that is above and below center, and match that percentage for the preview pane scroll
  • if the center control has nested fields, the above calculations would apply to the furthest nested child that intersects with center
  • measurements would need to be skewed when at or near the document edges so that both panes reach top and bottom simultaneously
  • update scroll position (smoothly) as content changes

Curious if anyone can think of potential issues?

@wraybowling
Copy link

This is something that I've also noticed, know a good bit about, and could possibly help solve. The resolution is going to be to keep track of just about everything related to focus, cursor position, and scrollTop positions, the heights of the two blocks that are related, and the heights of their scrollable viewports. Once you get all of that, it's very easy to write logic about whether the scroll position should move up or down in either direction.

@erquhart
Copy link
Contributor

Agreed! Feel free to play around with it, we can answer any questions that might come up here or in Gitter.

@zvimoe
Copy link

zvimoe commented Jul 29, 2019

I'm using custom previews, and thought of two possible solutions for this issue

Option 1
Adding a fifth prop to a preview component, that will trigger the 'focus' Function on a widget of a specific element this could enable you to click on the preview element to focus on it's widget and scroll there

for example

h('div', {'onClick':()=>{this.props.focusOnWidget('body')}}, this.props.widgetFor('body'))

Option 2
Adding a Function to set a custom preview prop in the custom widget controller similar tosetActiveStyle() and be sent to the custom preview to be used on the widget itself,
then anyone could create there own custom functionality
for example

const focusOnWidget = (whatever)=>{
      this.element.focus()
     /* and use whatever for whatever */
}

setCustomPreviewProp('focusOnWidget',this.focusOnWidget })
  • Option 2 would give the ability to mix the inputs in with the preview like in wordPress etc. I mean if you could pass a function to the preview then you could pass the widget to the preview as well.
    It could be amazing if someone could add it

@erquhart
Copy link
Contributor

erquhart commented Aug 28, 2019

Mixing controls in with the preview isn't a path we want to take right now - maybe somewhere way down the line, when Netlify CMS is abstract enough to serve as an engine with the site as a UI.

Option 1 is closer to what I've been thinking. The real challenge is that we don't know if the order of the controls matches the order in which they appear in the document. And if it does match, that could change depending on viewport size for responsive sites. We also don't know how many times a value is used in the preview. Any model of the two panes scrolling in the same direction at all times is optimistic at best, although going beyond that is a considerable engineering challenge.

Ideally we'd have some way to track preview elements that are tied to a given widget, without requiring a bunch of configuration. Haven't thought of a great way to do this apart from somehow indicating the relation in the preview template itself.

@stale
Copy link

stale bot commented Oct 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants