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

Support the components prop #260

Closed
4 tasks done
remcohaszing opened this issue Jan 13, 2023 · 2 comments · Fixed by #398
Closed
4 tasks done

Support the components prop #260

remcohaszing opened this issue Jan 13, 2023 · 2 comments · Fixed by #398
Labels
🗄 area/interface This affects the public interface 💪 phase/solved Post is done 🧒 semver/minor This is backwards-compatible change 🦋 type/enhancement This is great to have

Comments

@remcohaszing
Copy link
Member

Initial checklist

Problem

MDX allows to use the components prop to pass custom components.

{/* Greeting.mdx */}

Hello <Person name={name} />
import Greeting from './Greeting.mdx'

<Greeting components={{ Person: props => props.name }} name="Gary" />

The MDX code will be transformed to the following JSX before sending to TypeScript:

{/* Greeting.mdx */}

/**
 * Render the MDX contents.
 *
 * @param {MDXContentProps} props
 *   The props that have been passed to the MDX component.
 */
export default function MDXContent() {
  return <>
{/* Greeting.mdx */}
      <Person name={name} />
<>
}

// @ts-ignore
/** @typedef {Props} MDXContentProps */

Solution

We can extract all MDX elements and generate types for them to some extent. Components may be injected by a provider hook, so they should always be optional.

/**
 * @typedef {Props & { readonly components?: {
 *   readonly Person?: ((props: { name?: any }) => JSX.Element | null) | JSX.ClassComponent<{ name?: any }> | // XXX
 * } }} MDXContentProps
 */
  • Lower case components and JSX.IntrinsicElements
  • Function components
  • Class components
  • Components in nested objects

Alternatives

🤷

@remcohaszing remcohaszing added 🦋 type/enhancement This is great to have 🗄 area/interface This affects the public interface 🧒 semver/minor This is backwards-compatible change 👍 phase/yes Post is accepted and can be worked on labels Jan 13, 2023
@remcohaszing
Copy link
Member Author

New plan: Let the user explicitly define which components may be passed via DefinitelyTyped/DefinitelyTyped#67374. It’s still possible to override them locally using the Props typedef.

remcohaszing added a commit that referenced this issue Feb 12, 2024
This defines the `_components` variable in `_createMdxContent`. This
variable contains all components injected through the `components` prop,
a reference to `props`, and all local variables. All MDX JSX tags are
prefixed with `_components.` in the virtual code.

As a result, components declared in the `components` prop are allowed.
Components from both the `components` prop and local variables are
displayed in the autocomplete.

A downside of this approach is that documentation is lost for local
components. To mitigate this, only unknown JSX tags are prefixed.

Only MDX JSX tags are handled yet. JSX from estree not yet.

Refs #260
remcohaszing added a commit that referenced this issue Feb 12, 2024
This defines the `_components` variable in `_createMdxContent`. This
variable contains all components injected through the `components` prop,
a reference to `props`, and all local variables. All MDX JSX tags are
prefixed with `_components.` in the virtual code.

As a result, components declared in the `components` prop are allowed.
Components from both the `components` prop and local variables are
displayed in the autocomplete.

A downside of this approach is that documentation is lost for local
components. To mitigate this, only unknown JSX tags are prefixed.

Only MDX JSX tags are handled yet. JSX from estree not yet.

Refs #260
remcohaszing added a commit that referenced this issue Feb 12, 2024
This defines the `_components` variable in `_createMdxContent`. This
variable contains all components injected through the `components` prop,
a reference to `props`, and all local variables. All MDX JSX tags are
prefixed with `_components.` in the virtual code.

As a result, components declared in the `components` prop are allowed.
Components from both the `components` prop and local variables are
displayed in the autocomplete.

A downside of this approach is that documentation is lost for local
components. To mitigate this, only unknown JSX tags are prefixed.

Only MDX JSX tags are handled yet. JSX from estree not yet.

Refs #260

This comment has been minimized.

@remcohaszing remcohaszing added the 💪 phase/solved Post is done label Feb 22, 2024
@github-actions github-actions bot removed the 👍 phase/yes Post is accepted and can be worked on label Feb 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🗄 area/interface This affects the public interface 💪 phase/solved Post is done 🧒 semver/minor This is backwards-compatible change 🦋 type/enhancement This is great to have
Development

Successfully merging a pull request may close this issue.

1 participant