Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Svelte: add more general shrinkable path#63770

Merged
camdencheek merged 18 commits into
mainfrom
cc/shrinkable-path
Jul 12, 2024
Merged

Svelte: add more general shrinkable path#63770
camdencheek merged 18 commits into
mainfrom
cc/shrinkable-path

Conversation

@camdencheek

@camdencheek camdencheek commented Jul 10, 2024

Copy link
Copy Markdown
Member

This adds two new components for the common situation of needing to display a styled path.

  • DisplayPath handles splitting, coloring, spacing, slotting in a file icon, adding a copy button, and ensuring that no spaces get introduced when copying the path manually
  • ShrinkablePath is built on top of DisplayPath and adds the ability to collapse path elements into a dropdown menu

These are used in three places:

  • The file header. There should be no change in behavior except maybe a simplified DOM. This makes use of the "Shrinkable" version of the component.
  • The file search result header. This required carefully ensuring that the text content of the node is exactly equal to the path so that the character offsets are correct.
  • The file popover, where it is used for both the repo name (unlinkified version) and the file name (linkified version).

Fixes SRCH-718
Fixes SRCH-690

Video walkthrough

Test plan

Existing tests that I wrote previously cover most of this. I updated them where necessary. Added storybook pages for most of the variants. Lots of manual and visual testing. Interestingly, playwright seems to have simulated copy/paste behavior that does not match real browsers, so I could not rely on that for testing.

@cla-bot cla-bot Bot added the cla-signed label Jul 10, 2024
Comment thread client/common/src/util/highlightNode.ts Outdated
Comment on lines 153 to 154

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Rather than creating an empty span below (which complicates the DOM and messes with things like flex spacing), this just inserts an empty text node (a no-op).

Comment thread client/web-sveltekit/src/lib/dom.ts Outdated
Comment on lines 381 to 389

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I ran into some issues with the client locking up, and I realized I could limit the events that we respond to quite a bit. Instead of resizing every time anything in the subtree is mutated, we only need to resize when either 1) a direct child node is added or removed, or 2) a direct child node is resized.

This dramatically decreased the number of resize callbacks and made it much easier to reason about resize triggers.

Comment on lines 47 to 66

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Apologies for this monstrosity, but in order for highlighting to work correctly, there can be no extra whitespace nodes. Previously, this wasn't a big deal because we used the on:copy hook to remove the added spaces. Unfortunately, even after removing all the whitespace in the DOM, we still need the on:copy hook because the inline-block icon will always add a space when copied, even if it's not in th DOM.

Comment on lines 22 to 24

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No change in functionality. Just a small simplification.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We had this before but it doesn't work.
Seems to be a hidden 'gotcha' with Svelte: You cannot conditionally render slots, but Svelte only warns you about this for elements, not components.
Apparently this is not an issue in Svelte 5 anymore.

...baseConfig,
plugins: [...(baseConfig.plugins || []), 'prettier-plugin-svelte'],
overrides: [...(baseConfig.overrides || []), { files: '*.svelte', options: { parser: 'svelte' } }],
overrides: [...(baseConfig.overrides || []), { files: '*.svelte', options: { parser: 'svelte', htmlWhitespaceSensitivity: 'strict' } }],

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I came across a situation where formatting was adding whitespace in a way I could not get around with comments, so updated our formatter to always respect whitespace rules.

Comment on lines +44 to +48
<!--
NOTE: all the weird comments in here are being very careful to not
introduce any additional whitespace in the path container since that would
make the path invalid when copied from a selection
-->

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Apologies about this. It let me get rid of the "on copy" hook though, and also made it possible to correctly highlight a formatted path. Apparently Svelte 5 is getting saner whitespace rules, so we might be able to revisit this then.

Comment on lines +110 to +115
// HACK: The file icon is placed after the file name in the DOM so it
// doesn't add any spaces in the file path when copied. This visually
// reorders the last path element after the file icon.
.after {
order: 1;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is how I got around the "inline block svgs add a space to the copied text".

Comment on lines +1 to +6
<!--
@component
ShrinkablePath is a DisplayPath that can collapse its path items
into a dropdown menu to save space. It does not do this automatically,
and is usually used alongside a helper like `sizeToFit`.
-->

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

TIL that @component is needed for this to be treated as a doc comment.

Comment on lines +100 to +101
&:is(:hover, :focus-within) :global([data-copy-button]) {
opacity: 1;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Copy button now shows when the focus is inside the container

Comment on lines +24 to +30
<Tooltip {tooltip} placement="bottom"
><slot name="custom" {handleCopy}
><Button on:click={handleCopy} variant="icon" size="sm" aria-label={label}
><Icon inline icon={ILucideCopy} aria-hidden /></Button
></slot
></Tooltip
></span

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

More space removal. Again, sorry for the ugliness.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added a text-only menu item for unlinked dropdown menu.

@camdencheek camdencheek marked this pull request as ready for review July 11, 2024 21:53
@camdencheek camdencheek requested a review from a team July 11, 2024 21:54

@fkling fkling left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See my comments inline, especially about DiffView.

Comment thread client/web-sveltekit/src/lib/repo/filePopover/FilePopover.svelte Outdated
Comment on lines 22 to 24

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We had this before but it doesn't work.
Seems to be a hidden 'gotcha' with Svelte: You cannot conditionally render slots, but Svelte only warns you about this for elements, not components.
Apparently this is not an issue in Svelte 5 anymore.

Comment thread client/web-sveltekit/src/routes/search/FileSearchResultHeader.svelte Outdated
@camdencheek

camdencheek commented Jul 12, 2024

Copy link
Copy Markdown
Member Author

We had this before but it doesn't work.

Aah shoot. I always forget that slots cannot be passed in conditionally.

I've backed out this change, and added a mental note to check that when messing with slots. Thanks for the catch!

@camdencheek camdencheek merged commit 1218b49 into main Jul 12, 2024
@camdencheek camdencheek deleted the cc/shrinkable-path branch July 12, 2024 16:36
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants