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

[EuiCode][EuiCodeBlock] Various cleanups and bug fixes #5379

Merged
merged 31 commits into from
Nov 23, 2021

Conversation

cee-chen
Copy link
Contributor

@cee-chen cee-chen commented Nov 16, 2021

Summary

closes #5173
closes #5381
closes #5159

This PR primarily separates EuiCode and EuiCodeBlock from sharing as much unnecessary code/state as it does (since EuiCode is dramatically simpler) and DRYs out the code that they do share into utils.

Along the way however I noticed several other bugs and things to clean up - so I strongly recommend following along by commit. I should hopefully have left enough context and rationale for certain changes/decisions in my commit messages - please let me know if not!

QA

  • Inline EuiCode should look and work the same as before (sans bugfixes)
    • Long code strings now wrap normally
  • EuiCodeBlock should look and work the same as before (sans bugfixes)
  • Bugfixes
    • Go to https://eui.elastic.co/pr_5379/#/editors-syntax/code
    • Set the theme to Amsterdam
    • In the first EuiCodeBlock example, open the playground toggle
    • Set the overflowHeight to (e.g.) 150 in order to test virtualization and full screen behavior
    • Set fontSize to l and confirm the code font changes correctly
    • Set isVirtualized to true and confirm the line height remains the same on fontSize="l"
    • Set aria-label & data-test-subj to any text and inspect the underlying <code> example in the live playground. Confirm the props were correctly passed through
    • Toggle full screen mode, then press the Escape key. Confirm full screen mode is removed
    • Set the fontSize and paddingSize to s and then re-toggle full screen mode. Confirm that the font and padding are large in full screen mode
    • Close playground mode
    • Go to the whiteSpace="pre" example and click the full screen toggle button. Confirm that the text does not visually overlap the controls and that scrolling all the way to the right reveals the extent of the text.
    • Go to the virtualization example and scroll down to to the middle of the text. Click the full screen button and then close full screen mode. Confirm the non-full-screen code block has not been reset or blanked out.

Checklist

  • Check against all themes for compatibility in both light and dark modes
  • Checked in mobile
  • Checked in Chrome, Safari, Edge, and Firefox
  • Props have proper autodocs and playground toggles
  • Added documentation
  • Checked Code Sandbox works for any docs examples
  • Added or updated jest and cypress tests
  • Checked for breaking changes and labeled appropriately

⚠️ I don't think this PR contains any breaking changes since EuiCodeBlockImpl should have been an internal implementation only, but let me know if you disagree. I also don't think the CSS class changes on EuiCode is technically a breaking change, from my understanding of how we've handled CSS changes.

  • Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

+ write unit tests
+ organize utils with comment blocks
+ fix external link
+ remove prop already listed in CommonProps
+ remove prismjs class and language-* class - they didn't seem to be doing anything 🤷

+ remove language class - it also wasn't doing anything, and maybe belongs better as a data attribute

+ add unit tests for language and background props
+ removing any `inline` conditional logic

+ cleaning up props type/order
- The export shouldn't have been exported in the first place most likely, and hopefully wasn't being used by any consumers

- The testenv I'm less certain about but it looks like we used to `createPortal()` directly at one point and no longer do so/use EuiMaskOverlay, so it shouldn't be needed anymore
- By switching to render instead of html for snapshotting (tbh this seems easier to read in any case)

+ fix another instance in EuiDraggable that was bogarting this html.d.ts
- As far as I can tell, the prismjs CSS isn't doing anything in FF or Chrome (selections still work fine), and the language class is not doing anything either
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5379/

1 similar comment
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5379/

@thompsongl
Copy link
Contributor

⚠️ I don't think this PR contains any breaking changes since EuiCodeBlockImpl should have been an internal implementation only, but let me know if you disagree. I also don't think the CSS class changes on EuiCode is technically a breaking change, from my understanding of how we've handled CSS changes.

Agreed on all counts

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The visual improvements LGTM! I concentrated my review on looking for possible breaks and design code/docs.

src/themes/eui-amsterdam/overrides/_code_block.scss Outdated Show resolved Hide resolved
src/components/code/code.tsx Outdated Show resolved Hide resolved
src/components/code/_variables.scss Outdated Show resolved Hide resolved
src/components/code/_variables.scss Outdated Show resolved Hide resolved
src-docs/src/views/code/playground.js Outdated Show resolved Hide resolved
src-docs/src/views/code/code_example.js Outdated Show resolved Hide resolved
src/components/code/_index.scss Outdated Show resolved Hide resolved
+ Update full screen unit test to snapshot to show aria-label/data-test-subj correctly cascading
- the keydown was on the `<code>` element, but it needs to be on an element with `tabindex="0"` which is the `<pre>` element
+ virtualized line height on fontSize="l"
- Give EuiCode its own stylesheet/class name rather than being `euiCodeBlock--inline`

- Split out shared color/typography CSS into variable mixins

- Split out shared syntax styling CSS into mixin (tokens being in their own separate file is easier to parse also, just IMO)

- Adjust EuiCode classNames/snapshots accordingly

- rename override file to _code to match component folder
- Add reasonable inputs for lineNumbers and overflowHeight

- they take over options/types, but picking these allows users to quickly and easily see the difference in changing these props
+ fix incorrect `color="dark"` prop (not sure where this came from, it was also getting `...rest`ed when it should not have been)
+ fix some funky grammar
- role="presentation" wasn't the correct way to fix the jsx/a11y lint complaint and has actual screen reader ramifications we don't want

- After discussing with trevor, the jsx/a11y lint is over-zealous in this case, the end-behavior works better for users with tabIndex and onKeydown, and the rule can be disabled
- despite the comment which has apparently been incorrect for 4+ years
- Fixing the virtualization bug got me frustrated with working on the component. Various bits of different state and logic were scattered all over 450~ lines and made jumping up and down the file relatively annoying.

I decided to split this component up into several different hook/sub-component helpers based on several different complex pieces of functionality:

- overflow detection & observers
- copy functionality
- full screen functionality
- virtualization

This cleanup also:

- gets us to 100% statement coverage (woo)
- removes the need for certain lint disable comments (good times with ...rest)
- adds/cleans up several code comments

TBH, the file is still a little meaty to get through though the organization helps, if we continue to add more functionality to EuiCodeBlock it would be worth considering splitting up the separate sections/helpers into their own files.
…itence

- Allows for better line-wrapping of inline code
- Also removes `euiCodeTypography()` mixin
@cchaos
Copy link
Contributor

cchaos commented Nov 17, 2021

Pushed you a commit 1f6b548

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5379/

@cee-chen
Copy link
Contributor Author

Changes look super amazing and I LOVE getting rid of that extra span wrapper! Everything feels much cleaner now, thanks Caroline! 🧙

- This should have been added in 4e83aef, but I forgot
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5379/

Co-authored-by: Constance <constancecchen@users.noreply.github.com>
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5379/

@cee-chen cee-chen requested a review from cchaos November 18, 2021 21:35
@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5379/

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Design and design-code changes LGTM! Thanks for finding and fixing those bugs too.

I looked for any other backlog issues regarding EuiCodeBlock and found #5159. I investigated and I think if we just add white-space: pre; to .euiCodeBlock__line should fix that. It just means that virtualized code blocks cannot respect the whiteSpace prop and always forces topre.

@thompsongl
Copy link
Contributor

It just means that virtualized code blocks cannot respect the whiteSpace prop and always forces topre

Could enforce this in TypeScript with ExclusiveUnion

- because react-window virtualization sets the same height for each line, we need to enforce a white-space of `pre` for virtaulization

- Fix incorrect type union not actually enforcing `overflowHeight` (isVirtualized needs to be set to `false`), and add unit tests with ts-expect-error for incorrect props

- Improve prop docs dev experience slightly, move default comment blocks to to main props interface and have the ExclusiveUnion only handle prop differences
@cee-chen
Copy link
Contributor Author

5ddb91f should fix #5159, and also incidentally fix our type exclusive union not properly enforcing overflowHeight when isVirtualized is set

Copy link
Contributor

@thompsongl thompsongl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💟 Thank you!

Ran through the QA steps and otherwise put the examples through the paces. The only discernible difference is perhaps improved scroll updating in the virtualized blocks.

Just the one question

);

return (
<code className={classes} data-code-language={language} {...rest}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

data-code-language is new, right? A debugging helper?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's new! We previously had language as a CSS class but it wasn't doing anything in terms of styling. I removed the CSS class but figured it would be helpful to leave the current language in as an data attribute for debugging, like you said, and if consumers really needed to hook into it for some reason.

Comment on lines +449 to +451
/**
* Virtualization logic
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤩 this whole refactor

@cee-chen cee-chen requested a review from cchaos November 23, 2021 00:10
@cee-chen
Copy link
Contributor Author

jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_5379/

Copy link
Contributor

@cchaos cchaos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 I love tackling that backlog!

I also don't think any of this is a breaking change because I see them all as bug fixes.

@cee-chen
Copy link
Contributor Author

Wahoo! Thanks y'all. Merging!

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