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

Merge View: collapseUnchanged doesn't allow customizing "⦚ N unchanged lines ⦚" bars text #1467

Closed
VasylMarchuk opened this issue Nov 9, 2024 · 13 comments

Comments

@VasylMarchuk
Copy link

VasylMarchuk commented Nov 9, 2024

Describe the issue

The squiggly lines of the "⦚ N unchanged lines ⦚" text, hardcoded into collapseUnchanged bars for expanding hidden lines are cool, but we unfortunately couldn't fit them into our theme design, and the text isn't customizable :( It took us significant efforts to customize-hack the text with ninja :before and :after CSS elements, but the implementation is clumsy and unreliable.

Details

Знімок екрана 2024-11-09 о 17 06 57

Amount of ninja CSS we had to use for customizing the bar & text

Знімок екрана 2024-11-09 о 17 10 23

Suggestion

It would be great if we could provide a callback, or something, in collapseUnchanged options, that would be passed the number of lines, and return the text for those bars.

Reproduction link

We have a complete functioning demo of CodeMirror, wrapped into an Ember.js component over at https://app.codecrafters.io/demo/code-mirror, configurable with most of the standard extensions & their options in realtime, please feel free to test over there. It's ok if people discover the link here on GitHub, but please don't link to it, yet :)

Знімок екрана 2024-11-09 о 16 36 38

All of the documents used as examples in the Demo's document drop-down can be found here. The Ember.js component itself, which wraps CodeMirror, passes it all enabled extensions, and handles updates is here, just in case.

Our current CodeMirror & Merge versions

npm ls --depth=0 | grep codemirror
├── @codemirror/[email protected]
├── @codemirror/[email protected]
├── @uiw/[email protected]
├── [email protected]
@marijnh
Copy link
Member

marijnh commented Nov 9, 2024

The text is configurable via phrases, but indeed, the squigglies aren't. Would moving those into CSS before/after elements work for you?

@VasylMarchuk
Copy link
Author

VasylMarchuk commented Nov 10, 2024

Not really @marijnh, it wouldn't, for several reasons:

  • we're already using the :before element to add an icon expand-diff-top|middle|bottom.svg
  • in general using :before and :after triples the needed styles, as now you have to specify background & border + hover state + mousedown state, and everything else for all three — the element, the :before, and the :after — they aren't inherited

@VasylMarchuk
Copy link
Author

VasylMarchuk commented Nov 10, 2024

But also, there's a bigger problem with the "Expand xxx changed lines" bar, and I was about to create a separate issue just for this, but I guess I'll just put it here:

Please note how in, for example, VSCode and Github, the "Expand xxx changed lines" bar either extends into the gutter, or has a dedicated gutter element:

Знімок екрана 2024-11-10 о 14 06 02 Знімок екрана 2024-11-10 о 14 07 26

The problem

The way CodeMirror renders this bar — it is siblings with other lines in the document, it doesn't overlay the gutter, nor does it have a dedicated gutter element. This leads to a problem of the "gap":

Знімок екрана 2024-11-10 о 14 12 44 Знімок екрана 2024-11-10 о 14 11 41

Details

We have spent several weeks trying to solve this issue in various ways, coming up with CSS hacks, border color tweaks etc, but border is too noisy, gap is too noticeable. In addition, gutters div has varying width, depending on enabled gutters — and this voids any possible easy CSS solutions:

Знімок екрана 2024-11-10 о 14 12 11

Our temporary solution

Unfortunately all we could come up with, for now, is this implementation, our :before element has a crazy negative left margin and extends way beyond all possible gutters, but we couldn't solve the big padding before icon & text issue:

Знімок екрана 2024-11-10 о 14 21 38

@VasylMarchuk
Copy link
Author

VasylMarchuk commented Nov 10, 2024

So TLDR:

  • it would be cool if Expand xxx unchanged lines bar would overlay the gutter
  • or if not — a dedicated gutter element would solve a lot of related headache
  • it would be cool if we could provide a callback that would be responsible for generating the icon & text of the bar
    • or even better — a class, like we do with GutterMarker, for example, and it's toDOM method, responsible for rendering the entire DOM of the bar

UPD: I really should have stayed on point with customizing the text / removing the squiggles, sorry! Would you like me to create a separate issue for expand unchanged bar + gutter difficulties? But at least you know the background story now 😀

@marijnh
Copy link
Member

marijnh commented Nov 10, 2024

we're already using the :before element to add an icon expand-diff-top|middle|bottom.svg

Yes, and that'd override the default style, which is what you want here, right?

in general using :before and :after triples the needed styles, as now you have to specify background & border + hover state + mousedown state, and everything else for all three — the element, the :before, and the :after — they aren't inherited

:before/:after elements definitely do inherit the styles of their parent element.

Does gutterWidgetClass help with your gutter styling? If not, please do open a separate issue.

@VasylMarchuk
Copy link
Author

VasylMarchuk commented Nov 11, 2024

:before/:after elements definitely do inherit the styles of their parent element

They do for some, but not for all, for example background and border aren't inherited, which are the ones we actually care about most:

.decorate-me {
  margin: 30px 50px;
  padding: 50px 30px;
  background: red;
  border: 3px solid green;
}

.decorate-me:before {
  content: "Pseudo text";
  outline: 1px dashed navy;
  margin-left: -70px;
}

image

In addition, if we set the same background color for both the element & pseudo-element: we can't use rgba, because the pseudo gets transparency over transparency -> a different color.

Also: when trying to set an svg icon as a background for the :before element, I couldn't find a way to specify the svg color: color doesn't apply, and using fill: currentColor in the svg itself doesn't work either. We had to use separate svg files for icons in hover state, mousedown state, and then again for the Dark skin: so 18 icons in total.

@VasylMarchuk
Copy link
Author

VasylMarchuk commented Nov 11, 2024

Please let me spend a couple hours to experiment with the squiggles being in before/after pseudo elements and if that helps address our concerns, I will come back to you once I know.

UPD: Still experimenting, quite tricky to simulate on the fly, plus had another urgent task.

@marijnh
Copy link
Member

marijnh commented Nov 11, 2024

They do for some, but not for all, for example background and border aren't inherited, which are the ones we actually care about most:

Those never are—CSS inheritance generally only applies to properties where inheritance makes sense.

@VasylMarchuk
Copy link
Author

VasylMarchuk commented Dec 1, 2024

Alright, sorry it took so long to test, I can confirm that this solves at least the need to cover up the squiggly lines manually, and should simplify the necessary style overrides, so let's go ahead and maybe move squiggly lines into :before and :after elements? @marijnh

@marijnh
Copy link
Member

marijnh commented Dec 1, 2024

Attached patch makes this change.

@VasylMarchuk
Copy link
Author

Big thanks, I will start using this and will update our styles shortly!

@VasylMarchuk
Copy link
Author

VasylMarchuk commented Dec 15, 2024

Hey @marijnh, would you be so kind to give an example of using gutterWidgetClass?

Does gutterWidgetClass help with your gutter styling?

For example, I'd like to add a class collapseUnchangedBarGutter to all gutter elements (inside cm-lineNumbers, cm-foldGutter, cm-changeGutter) that appear next to Collapse Unchanged widgets:

Знімок екрана 2024-12-15 о 14 29 28

Is that possible? Did I understand correctly that this is the purpose of gutterWidgetClass?

I've searched the entire Internet and haven't been able to find a single usage example, and the docs are scarce about this.

In fact, I haven't even been able to import it:

import { gutterWidgetClass } from '@codemirror/view';
// --> '"@codemirror/view"' has no exported member named 'gutterWidgetClass'. Did you mean 'gutterLineClass'?

Am I supposed to import it [somehow] and then just add it to the list of extensions? Configured with WidgetType and BlockInfo? Also where would BlockInfo come from?

PS: Big thanks in advance, sorry for late response on this, currently changing our styles to match your latest patches

@marijnh
Copy link
Member

marijnh commented Dec 15, 2024

gutterWidgetClass was added in @codemirror/view 6.32.0. Maybe you're using an older version? The way to use it is to define a gutter marker and make the predicate you give to gutterWidgetClass check whether it is dealing with a merge widget, and if so, return such a widget. Though I guess, since @codemirror/merge doesn't export the widget type, doing this check might be a bit tricky.

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

No branches or pull requests

2 participants