Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
54b690c
Move getNextFocusableElement into its own file
colebemis Sep 20, 2022
9c38077
Create useTypeahead hook
colebemis Sep 20, 2022
f7b8a81
Create useActiveDescendant hook
colebemis Sep 20, 2022
0302439
Add typeahead tests
colebemis Sep 20, 2022
667f9ac
Create loud-toys-explode.md
colebemis Sep 21, 2022
06a8375
Merge branch 'main' into treeview-typeahead
colebemis Sep 21, 2022
6118df5
Refactor useTypeahead to work better with useEffect hook
colebemis Sep 21, 2022
c2f0c6c
Use useSafeTimeout hook
colebemis Sep 22, 2022
b56082d
Merge branch 'main' into treeview-typeahead
colebemis Sep 22, 2022
b92c9ca
Allow expanded state to be controlled
colebemis Sep 26, 2022
bddb639
Add tests for useControllableState hook
colebemis Sep 26, 2022
9908de9
Fix logic bug when expanding current path
colebemis Sep 26, 2022
efcaf70
Test controlled state
colebemis Sep 26, 2022
10159c6
Merge branch 'main' into treeview-control-expanded
colebemis Sep 26, 2022
2457ea4
Remove unused eslint disables
colebemis Sep 26, 2022
86ca61b
Create serious-adults-protect.md
colebemis Sep 26, 2022
e9ebd6a
Add current prop to LinkItem prop table
colebemis Sep 26, 2022
4f6de01
Merge branch 'treeview-control-expanded' of github.com:primer/react i…
colebemis Sep 26, 2022
eeaf486
Create stable setState function
colebemis Sep 28, 2022
06205b3
Refactor effects
colebemis Sep 28, 2022
480261d
Create jump to menu in story
colebemis Sep 28, 2022
8d355fa
Merge branch 'main' into treeview-control-expanded
colebemis Sep 28, 2022
4750160
Add conrolled example to docs
colebemis Sep 28, 2022
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
5 changes: 5 additions & 0 deletions .changeset/serious-adults-protect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

TreeView: Allow expanded state to be controlled
10 changes: 9 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
// rules which apply to JS, TS, etc.
"rules": {
"no-shadow": 0,
"react/prop-types": 0,
"react/display-name": 0,
"react-hooks/exhaustive-deps": "error",
Expand All @@ -69,7 +70,6 @@
"rules": {
"eslint-comments/no-use": 0,
"import/no-namespace": 0,
"no-shadow": 0,
"no-unused-vars": [
"error",
{
Expand All @@ -94,6 +94,14 @@
{
"argsIgnorePattern": "^_"
}
],
"@typscript-eslint/no-shadow": 0,
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-ignore": "allow-with-description"
}
]
}
},
Expand Down
72 changes: 67 additions & 5 deletions docs/content/TreeView.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,35 @@ description: A hierarchical list of items where nested items can be expanded and
</nav>
```

### With controlled expanded state

```javascript live noinline drafts
function ControlledTreeView() {
const [expanded, setExpanded] = React.useState(false)

return (
<Box sx={{display: 'grid', gap: 2}}>
<Button onClick={() => setExpanded(!expanded)}>{expanded ? 'Collapse' : 'Expand'}</Button>
<nav aria-label="File navigation">
<TreeView aria-label="File navigation">
<TreeView.Item expanded={expanded} onExpandedChange={setExpanded}>
src
<TreeView.SubTree>
<TreeView.LinkItem href="#">Avatar.tsx</TreeView.LinkItem>
<TreeView.LinkItem href="#" current>
Button.tsx
</TreeView.LinkItem>
</TreeView.SubTree>
</TreeView.Item>
</TreeView>
</nav>
</Box>
)
}

render(<ControlledTreeView />)
```

## Props

### TreeView
Expand All @@ -82,18 +111,31 @@ description: A hierarchical list of items where nested items can be expanded and

<PropsTable>
<PropsTableRow name="children" type="React.ReactNode" required />
<PropsTable
<PropsTableRow
name="current"
type="boolean"
defaultValue="false"
description="Whether the item is the current item. No more than one item should be current at once."
description="Whether the item is the current item. No more than one item should be current at once. The path to the current item will be expanded by default."
/>
<PropsTableRow
name="defaultExpanded"
type="boolean"
description="The expanded state of the item when it is initially rendered. Use when you do not need to control the state."
/>
<PropsTableRow
name="expanded"
type="boolean"
description="The controlled expanded state of item. Must be used in conjunction with onExpandedChange."
/>
<PropsTableRow
name="onExpandedChange"
Copy link
Member

Choose a reason for hiding this comment

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

Is there a good rule of thumb to follow for when to use on<State>Change(value), as in onExpandedChange(), versus onChange(state)?

type="(expanded: boolean) => void"
description="Event handler called when the expanded state of the item changes."
/>
<PropsTableRow name="defaultExpanded" type="boolean" description="Whether the item is expanded by default." />
<PropsTableRow
name="onSelect"
type="(event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void"
/>
<PropsTableRow name="onToggle" type="(isExpanded: boolean) => void" />
{/* <PropsTableSxRow /> */}
</PropsTable>

Expand All @@ -113,11 +155,31 @@ description: A hierarchical list of items where nested items can be expanded and
</>
}
/>
<PropsTableRow
name="current"
type="boolean"
defaultValue="false"
description="Whether the item is the current item. No more than one item should be current at once. The path to the current item will be expanded by default."
/>
<PropsTableRow
name="defaultExpanded"
type="boolean"
description="The expanded state of the item when it is initially rendered. Use when you do not need to control its state."
/>
<PropsTableRow
name="expanded"
type="boolean"
description="The controlled expanded state of item. Must be used in conjunction with onExpandedChange."
/>
<PropsTableRow
name="onExpandedChange"
type="(expanded: boolean) => void"
description="Event handler called when the expanded state of the item changes."
/>
<PropsTableRow
name="onSelect"
type="(event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void"
/>
<PropsTableRow name="onToggle" type="(isExpanded: boolean) => void" />
{/* <PropsTableSxRow /> */}
</PropsTable>

Expand Down
1 change: 0 additions & 1 deletion src/PageLayout/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ const Root: React.FC<React.PropsWithChildren<PageLayoutProps>> = ({
<Box
ref={rootRef}
style={{
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore TypeScript doesn't know about CSS custom properties
'--sticky-pane-height': stickyPaneHeight
}}
Expand Down
1 change: 0 additions & 1 deletion src/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ function defaultHrefBuilder(pageNum: number) {
return `#${pageNum}`
}

// eslint-disable-next-line @typescript-eslint/no-empty-function
function noop() {}

Pagination.defaultProps = {
Expand Down
Loading