Skip to content

Add inline portal node support#45

Merged
pimterry merged 9 commits into
httptoolkit:mainfrom
aeharding:span
Apr 7, 2025
Merged

Add inline portal node support#45
pimterry merged 9 commits into
httptoolkit:mainfrom
aeharding:span

Conversation

@aeharding
Copy link
Copy Markdown
Contributor

@aeharding aeharding commented Nov 18, 2024

This adds createHtmlInlinePortalNode to the public api, which creates a <span> instead of <div> wrapper.

This is helpful when portalling into phrasing content. For example, placing a portal inside <p> [0]

Without this, React will emit hydration warnings.

Resolves #44

[0] https://html.spec.whatwg.org/multipage/grouping-content.html#the-p-element

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Nov 18, 2024

CLA assistant check
All committers have signed the CLA.

This adds `createHtmlInlinePortalNode` to the public api,
which creates a `<span>` instead of `<div>` wrapper.

This is helpful when portalling into phrasing content.
For example, placing a portal inside `<p>` [0]

Without this, React will emit hydration warnings.

Resolves httptoolkit#44

[0] https://html.spec.whatwg.org/multipage/grouping-content.html#the-p-element
Comment thread src/index.tsx
Comment thread stories/html.stories.js Outdated
import { storiesOf } from '@storybook/react';

import { createHtmlPortalNode, createSvgPortalNode, InPortal, OutPortal } from '..';
import { createHtmlPortalNode, createHtmlInlinePortalNode, InPortal, OutPortal } from '..';
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Left createHtmlPortalNode the same to avoid breaking change (e.g. to createHtmlBlockPortalNode)

I think most people will want the block version anyways.

@aeharding
Copy link
Copy Markdown
Contributor Author

For naming options, curious your thoughts on:

  • createHtmlInlinePortalNode vs
  • createHtmlPhrasingPortalNode

Perhaps "phrasing" is more accurate than "inline" (but maybe less well understood) in regards to when you should use it.

Copy link
Copy Markdown
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

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

Interesting, thanks! This makes sense, but I'm not sure about the API - I don't think this should fit into the html vs svg current split, it's not a different type of DOM as such.

What about keeping the existing API, but adding this to options? Is that practical? With that, this could be configured like:

createHtmlPortalNode({ containerElement: 'span' });

I haven't tested, but that looks possible and would keep the API simpler whilst also allowing other different element types in future. Does that make sense?

@aeharding
Copy link
Copy Markdown
Contributor Author

@pimterry Yeah, I can change it.

Should I remove createSvgPortalNode then?

@pimterry
Copy link
Copy Markdown
Member

Should I remove createSvgPortalNode then?

No - I think we should still have two methods for the different fundamental types of portal (HTML/SVG), I just don't think we should create new methods for each individual element that could be used. The SVG vs HTML difference isn't just the name of the element used - for example SVG portals only allow SVG children, and the placeholder node has to be created in the http://www.w3.org/2000/svg namespace.

@aeharding aeharding requested a review from pimterry March 23, 2025 15:40
@aeharding
Copy link
Copy Markdown
Contributor Author

Hi @pimterry, sorry for the delay! I just got around to making the changes for your feedback. Thanks!

Copy link
Copy Markdown
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

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

Thanks for the updates @aeharding! Code looks good, and I think this works nicely and solves the issue.

An interesting point though is that this constrains the possible elements to just div or span. It looks like it would be easy to change elementType back to just html/svg, and then allow any string as containerElement. Is the limitation necessary/is allowing wider config useful?

I haven't thought about this in great depth, but it seems like it should work and might be more flexible for other use cases without any significant change in the complexity here. What do you think? Happy to just merge as-is if it's problematic for some reason, let me know what you think.

@aeharding
Copy link
Copy Markdown
Contributor Author

Hi @pimterry, that makes sense. Please check out my adjustments

Comment thread src/index.tsx
Copy link
Copy Markdown
Member

@pimterry pimterry left a comment

Choose a reason for hiding this comment

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

Nice work, thanks @aeharding. Merged 👍

@pimterry pimterry merged commit c66c63d into httptoolkit:main Apr 7, 2025
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

Successfully merging this pull request may close these issues.

Can't portal inside inline html elements without React hydration warnings

3 participants