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

Not rendering newlines in DataGridCell #497

Open
timheuer opened this issue Jul 7, 2023 · 11 comments
Open

Not rendering newlines in DataGridCell #497

timheuer opened this issue Jul 7, 2023 · 11 comments
Assignees
Labels
bug Something isn't working

Comments

@timheuer
Copy link
Member

timheuer commented Jul 7, 2023

I think I might be hitting same/variation as #484 when the content being rendered from the data source has newlines.

Example content:

ZZZAboutHeader22 
  
test  Test

How it is rendered in the cell:
image

Expected rendering in the cell:
image

@timheuer timheuer added the bug Something isn't working label Jul 7, 2023
@hawkticehurst
Copy link
Member

hawkticehurst commented Oct 18, 2023

Hey @timheuer! I'm circling back to old issues this week and have some updates and a question!

Currently, it looks like data grid cells have a CSS declaration that might be causing this issue. Each cell is set with white-space: wrap; which actually seems to be a non-valid value for this property (whoops 😅) and defaults to collapsing all whitespace (including newlines) as a result. I've experimented with other values and landed on pre-line as the option that gets the closest to what you're looking for.

With that said, extra newlines are added when this value is present (for a yet-to-be-determined reason) and results in a cell that has more spacing/padding than it should.

Given the following code:

<vscode-data-grid id="default-grid" grid-template-columns="1fr 1fr 1fr 1fr" aria-label="Default"></vscode-data-grid>
const defaultDataGrid = document.getElementById("default-grid") as DataGrid;
defaultDataGrid.rowsData = [
  {
    column1: "Cell Data\nHello world",
    column2: "Cell Data",
    column3: "Cell Data",
    column4: "Cell Data",
  },
  // More data...
];
vscode-data-grid-cell {
  white-space: pre-line;
}

The following output is produced:

Screenshot 2023-10-18 at 1 05 39 PM

A question for you:

I'll try and experiment with all of this a bit more, but I've realized it would really help to have more details on how you're trying/hoping to implement and use this kind of functionality.

Specifically, how will newlines get added? Will it be like I've demonstrated above (i.e. adding intentional newline characters to strings), or be the result of user interaction/editing, since I know you've been working on an editable data grid for a while correct, or something else entirely?

@timheuer
Copy link
Member Author

The newlines would likely mostly be editing by interacting normally with keystrokes, e.g., "return" key activity.

@hawkticehurst
Copy link
Member

hawkticehurst commented Oct 18, 2023

Okay cool, and to extra extra clear those interactions are enabled with the contenteditable attribute right?

The casual update is I resolved the extra spacing issue, but if newlines will mainly come as a result of contenteditable I think I just discovered a new problem

@timheuer
Copy link
Member Author

those interactions are enabled with the contenteditable attribute right?

Correct.

@hawkticehurst
Copy link
Member

Okay, so I thinkkkk I may have something that works, but I would love a sanity check to make sure I haven't missed anything, especially in the editable data grid category.

I created a demo extension that shows off these changes using the editable-data-grid sample extension as a starting point. If you have some time next week to test it out and see if there are any glaring issues I'd greatly appreciate that.

We could even hop on a call to really chat through the details and potentially save some async back and forth if you have the time. Regardless, let me know and have a great weekend!

@timheuer
Copy link
Member Author

@hawkticehurst - looks good! spent about 7 minutes typing around, etc. -- like you note the arrow keys not being able to navigate the cursor while in edit.

is the resulting new line saving as \n or <br/>?

@hawkticehurst
Copy link
Member

is the resulting new line saving as \n or <br/>?

This is the part of the solution (and contenteditable at large?) I'm most uncertain about... I've been working on cataloging this all afternoon and a few scenarios occur when I look at dev tools while testing everything.

Scenario 1: \n is (seemingly) only used when directly embedded into predefined strings

Given the following code:

basicDataGrid.rowsData = [
    {
      name: "Tasha Hess\n\nHere's some text that already\ncomes with newlines included!",
      email: "tasha.hess@protonmail.couk",
      phone: "(578) 194-4268",
      country: "Canada",
    },
    // Other data...
];

A single string is inserted into the DOM (with the \n directly embedded in the string –– even though you can't see them in dev tools).

Image

And corresponds to this rendered output:

Image

Scenario 2: A combo of &nbsp; and separate strings are used when shift + enter keys are clicked

So a few different things happen when the shift + enter keys are clicked.

The first time these keys are clicked (used with existing content in a cell), a separate string with three instances of &nbsp; (i.e. the HTML entity for a "non-breaking space") is created.

Image

As you then type out new content in the newline the text is appended before the &nbsp; characters.

Image

This corresponds to the following rendered data grid cell:

Image

If you keep clicking shift + enter to add even more newlines the number and location of &nbsp; entities don't change, but each new line is associated with a separate string.

Image

Here's the corresponding output:

Image

Scenario 3: <br> is used when deleting lines of content?

This is one of the more perplexing scenarios for me. If I were to click backspace to delete the previously shown output, once I get to the point where there's one line of content in the cell a <br> element is added for some (unknown to me) reason.

The separate strings of content and &nbsp; entities will be deleted (as expected), but then this <br> tag will be added??

Image

Current thoughts/conclusions

From the brief bit of googling I've been doing this behavior seems to be coming from contenteditable more than the changes to CSS I've made.

Also while these weird inconsistencies make me uncomfortable from a programming perspective, it doesn't seem to affect the actual experience of creating newlines in a data grid cell... so maybe it's fine??

Also maybe you know more about how contenteditable should be behaving vs not?

@hawkticehurst
Copy link
Member

hawkticehurst commented Oct 21, 2023

One more update before the weekend, I finally figured out how to prevent the FAST data-grid arrow key behavior when in cell edit mode!

I updated the demo app with the change, so feel free to check it out (see the handleKeydown function in src/webview/main.ts) and do another round of testing on the demo.

I'll also update the actual editable-data-grid sample extension next week too.

@hawkticehurst
Copy link
Member

@timheuer okay another interesting update.

I've been updating the editable data grid sample today with the new features (i.e. render new line with shift + enter and enable cursor movement when in edit mode) and I realized that without any of the earlier mentioned CSS changes to our core data-grid component, rendering newlines actually works just fine and is muchhh more consistent.

Namely, without the CSS changes only <br> is used to render newlines:

Image

Image

If you have some cycles to try this out, I'd love your feedback on whether this might be a better/more consistent solution for your needs.

The important parts are:

  • When in cell edit mode, do nothing when enter + shift are clicked –– this will render a newline
  • When in cell edit mode, stop event propagation –– this will allow arrow keys to move the cursor
function handleKeydown(e: KeyboardEvent, cell: DataGridCell) {
  if (!cell.hasAttribute("contenteditable") || cell.getAttribute("contenteditable") === "false") {
    if (e.key === "Enter") {
      // Enable cell edit mode
      e.preventDefault();
      setCellEditable(cell);
    }
  } else {
    if (e.key === "Enter" && e.shiftKey) {
      // When in cell edit mode do nothing, let default behavior execute –– render newline
    } else if (e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "ArrowUp" || e.key === "ArrowDown") {
      // When in cell edit mode, arrow keys will move the cursor
      // This will stop event propagation so that the underlying FAST 
      // data-grid arrow events are not triggered
      e.stopPropagation();
    } else if (e.key === "Enter" || e.key === "Escape") {
      // Exit cell edit mode
      e.preventDefault();
      syncCellChanges(cell);
      unsetCellEditable(cell);
    }
  }
}

The only drawback of this solution is that you cannot get a string predefined string to render a newline when using the rowsData API, but since you mentioned you expect user input to be the primary method of rendering newlines I'm hoping that trade might be okay.

@timheuer
Copy link
Member Author

Thanks, I think
will not be what I'm looking for in this scenario as my use cases are for localized strings that may/may not be HTML use cases. For context my extension: https://marketplace.visualstudio.com/items?itemName=TimHeuer.resx-editor

@hawkticehurst
Copy link
Member

Okay got it! Thanks for the extra context, I'll take a look at your extension tomorrow and go from there

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants