diff --git a/.github/skills/style-guide/SKILL.md b/.github/skills/style-guide/SKILL.md index 71fab2f1be8..1edc5de484f 100644 --- a/.github/skills/style-guide/SKILL.md +++ b/.github/skills/style-guide/SKILL.md @@ -20,6 +20,15 @@ deviates from the style guide, call out the reason. In addition, there are a set of topics below that may be used for guidance on a specific topic. Consult this to see if any apply to the task at hand. -| Topic | Description | Link | -| :-------------------- | :------------------------------------------------------------------------ | :------------------------------------------------------- | -| Component prop naming | Use when deciding or evaluating the name for a prop in a React component. | [component-prop-naming](./docs/component-prop-naming.md) | +| Topic | Description | Link | +| :-------------------- | :-------------------------------------------------------------------------------- | :------------------------------------------------------- | +| Component prop naming | Use when deciding or evaluating the name for a prop in a React component. | [component-prop-naming](./docs/component-prop-naming.md) | +| Component prop types | Use when designing or reviewing component prop types, including slot-based props. | [component-prop-types](./docs/component-prop-types.md) | + +## Updating this skill + +Keep `SKILL.md` minimal: usage instructions and a table linking to topics. +When adding or updating guidance, edit the relevant topic under `docs/`. +If no existing topic fits, create a new topic file under `docs/` and add a row +to the table with a link and a description of when to consult it. Keep detailed +guidance and examples in topic files rather than in `SKILL.md`. diff --git a/.github/skills/style-guide/docs/component-prop-types.md b/.github/skills/style-guide/docs/component-prop-types.md new file mode 100644 index 00000000000..1b2bae56e00 --- /dev/null +++ b/.github/skills/style-guide/docs/component-prop-types.md @@ -0,0 +1,53 @@ +# Component Prop Types + +Use these conventions when designing or reviewing prop types for Primer React components. + +## Prefer `React.ReactNode` for slot-based props + +When designing props that fill a content slot, such as `leadingVisual`, +`trailingVisual`, or `icon`, prefer `React.ReactNode` rather than component types +or functions that return elements. This accepts JSX as well as other renderable +content and conditional values such as `showIcon && `. Use +`React.ReactElement` only when the API specifically requires a single element. + +This lets consumers pass configured JSX directly without wrapping it in an inline +component. It also allows Server Components to pass JSX through these props to +Client Components, whereas component functions cannot be passed across that +boundary. + + + + + +
UnpreferredPreferred
+ +```tsx +type Props = { + leadingVisual?: React.ElementType + trailingVisual?: React.ElementType +} + +function Usage() { + return } /> +} +``` + + + +```tsx +type Props = { + leadingVisual?: React.ReactNode + trailingVisual?: React.ReactNode +} + +function Usage({showSearch}: {showSearch: boolean}) { + return } trailingVisual={} /> +} +``` + +
+ +Reserve render props for cases where the consumer needs state or other values +from the component to determine what to render. When extending an existing +component-type slot API to accept elements, preserve the existing form for +backwards compatibility and prefer the element form in documentation and stories.