Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions .github/skills/style-guide/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
53 changes: 53 additions & 0 deletions .github/skills/style-guide/docs/component-prop-types.md
Original file line number Diff line number Diff line change
@@ -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 && <SearchIcon />`. 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.

<table>
<thead><tr><th>Unpreferred</th><th>Preferred</th></tr></thead>
<tbody>
<tr><td>

```tsx
type Props = {
leadingVisual?: React.ElementType
trailingVisual?: React.ElementType
}

function Usage() {
return <Example leadingVisual={SearchIcon} trailingVisual={() => <ChevronDownIcon size={16} />} />
}
```

</td><td>

```tsx
type Props = {
leadingVisual?: React.ReactNode
trailingVisual?: React.ReactNode
}

function Usage({showSearch}: {showSearch: boolean}) {
return <Example leadingVisual={showSearch && <SearchIcon />} trailingVisual={<ChevronDownIcon size={16} />} />
}
```

</td></tr>
</tbody></table>

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.
Loading