1
1
import { ChevronDownIcon } from '@primer/octicons-react'
2
2
import { useSSRSafeId } from '@react-aria/ssr'
3
3
import React , { isValidElement } from 'react'
4
+ import styled from 'styled-components'
4
5
import { ActionList } from '../ActionList'
5
6
import Box from '../Box'
6
7
import StyledOcticon from '../StyledOcticon'
8
+ import sx , { merge , SxProp } from '../sx'
7
9
8
10
// ----------------------------------------------------------------------------
9
11
// NavList
10
12
11
13
export type NavListProps = {
12
14
children : React . ReactNode
13
- } & React . ComponentProps < 'nav' >
15
+ } & SxProp &
16
+ React . ComponentProps < 'nav' >
17
+
18
+ const NavBox = styled . nav < SxProp > ( sx )
14
19
15
- // TODO: sx prop
16
20
const Root = React . forwardRef < HTMLElement , NavListProps > ( ( { children, ...props } , ref ) => {
17
21
return (
18
- < nav ref = { ref } { ...props } >
22
+ < NavBox { ...props } ref = { ref } >
19
23
< ActionList > { children } </ ActionList >
20
- </ nav >
24
+ </ NavBox >
21
25
)
22
26
} )
23
27
@@ -30,12 +34,11 @@ export type NavListItemProps = {
30
34
children : React . ReactNode
31
35
href ?: string
32
36
'aria-current' ?: 'page' | 'step' | 'location' | 'date' | 'time' | 'true' | 'false' | boolean
33
- }
37
+ } & SxProp
34
38
35
- // TODO: sx prop
36
39
// TODO: as prop
37
40
const Item = React . forwardRef < HTMLAnchorElement , NavListItemProps > (
38
- ( { href, 'aria-current' : ariaCurrent , children} , ref ) => {
41
+ ( { href, 'aria-current' : ariaCurrent , children, sx : sxProp = { } } , ref ) => {
39
42
const { depth} = React . useContext ( SubNavContext )
40
43
41
44
// Get SubNav from children
@@ -54,7 +57,7 @@ const Item = React.forwardRef<HTMLAnchorElement, NavListItemProps>(
54
57
)
55
58
56
59
return (
57
- < ItemWithSubNav subNav = { subNav } subNavContainsCurrentItem = { Boolean ( currentItem ) } >
60
+ < ItemWithSubNav subNav = { subNav } subNavContainsCurrentItem = { Boolean ( currentItem ) } sx = { sxProp } >
58
61
{ childrenWithoutSubNav }
59
62
</ ItemWithSubNav >
60
63
)
@@ -66,11 +69,14 @@ const Item = React.forwardRef<HTMLAnchorElement, NavListItemProps>(
66
69
href = { href }
67
70
aria-current = { ariaCurrent }
68
71
active = { Boolean ( ariaCurrent ) && ariaCurrent !== 'false' }
69
- sx = { {
70
- paddingLeft : depth > 0 ? 5 : null , // Indent sub-items
71
- fontSize : depth > 0 ? 0 : null , // Reduce font size of sub-items
72
- fontWeight : depth > 0 ? 'normal' : null // Sub-items don't get bolded
73
- } }
72
+ sx = { merge < SxProp [ 'sx' ] > (
73
+ {
74
+ paddingLeft : depth > 0 ? 5 : null , // Indent sub-items
75
+ fontSize : depth > 0 ? 0 : null , // Reduce font size of sub-items
76
+ fontWeight : depth > 0 ? 'normal' : null // Sub-items don't get bolded
77
+ } ,
78
+ sxProp
79
+ ) }
74
80
>
75
81
{ children }
76
82
</ ActionList . LinkItem >
@@ -87,17 +93,16 @@ type ItemWithSubNavProps = {
87
93
children : React . ReactNode
88
94
subNav : React . ReactNode
89
95
subNavContainsCurrentItem : boolean
90
- }
96
+ } & SxProp
91
97
92
98
const ItemWithSubNavContext = React . createContext < { buttonId : string ; subNavId : string } > ( {
93
99
buttonId : '' ,
94
100
subNavId : ''
95
101
} )
96
102
97
- // TODO: sx prop
98
103
// TODO: ref prop
99
104
// TODO: Animate open/close transition
100
- function ItemWithSubNav ( { children, subNav, subNavContainsCurrentItem} : ItemWithSubNavProps ) {
105
+ function ItemWithSubNav ( { children, subNav, subNavContainsCurrentItem, sx : sxProp = { } } : ItemWithSubNavProps ) {
101
106
const buttonId = useSSRSafeId ( )
102
107
const subNavId = useSSRSafeId ( )
103
108
// SubNav starts open if current item is in it
@@ -114,9 +119,12 @@ function ItemWithSubNav({children, subNav, subNavContainsCurrentItem}: ItemWithS
114
119
// When the subNav is closed, how should we indicated that the subNav contains the current item?
115
120
active = { ! isOpen && subNavContainsCurrentItem }
116
121
onClick = { ( ) => setIsOpen ( open => ! open ) }
117
- sx = { {
118
- fontWeight : subNavContainsCurrentItem ? 'bold' : null // Parent item is bold if any of it's sub-items are current
119
- } }
122
+ sx = { merge < SxProp [ 'sx' ] > (
123
+ {
124
+ fontWeight : subNavContainsCurrentItem ? 'bold' : null // Parent item is bold if any of it's sub-items are current
125
+ } ,
126
+ sxProp
127
+ ) }
120
128
>
121
129
{ children }
122
130
{ /* What happens if the user provides a TrailingVisual? */ }
@@ -141,14 +149,13 @@ function ItemWithSubNav({children, subNav, subNavContainsCurrentItem}: ItemWithS
141
149
142
150
type NavListSubNavProps = {
143
151
children : React . ReactNode
144
- }
152
+ } & SxProp
145
153
146
154
const SubNavContext = React . createContext < { depth : number } > ( { depth : 0 } )
147
155
148
- // TODO: sx prop
149
156
// TODO: ref prop
150
157
// NOTE: SubNav must be a direct child of an Item
151
- const SubNav = ( { children} : NavListSubNavProps ) => {
158
+ const SubNav = ( { children, sx : sxProp = { } } : NavListSubNavProps ) => {
152
159
const { buttonId, subNavId} = React . useContext ( ItemWithSubNavContext )
153
160
const { depth} = React . useContext ( SubNavContext )
154
161
@@ -165,7 +172,18 @@ const SubNav = ({children}: NavListSubNavProps) => {
165
172
166
173
return (
167
174
< SubNavContext . Provider value = { { depth : depth + 1 } } >
168
- < Box as = "ul" id = { subNavId } aria-labelledby = { buttonId } sx = { { padding : 0 , margin : 0 } } >
175
+ < Box
176
+ as = "ul"
177
+ id = { subNavId }
178
+ aria-labelledby = { buttonId }
179
+ sx = { merge < SxProp [ 'sx' ] > (
180
+ {
181
+ padding : 0 ,
182
+ margin : 0
183
+ } ,
184
+ sxProp
185
+ ) }
186
+ >
169
187
{ children }
170
188
</ Box >
171
189
</ SubNavContext . Provider >
@@ -198,19 +216,20 @@ Divider.displayName = 'NavList.Divider'
198
216
// ----------------------------------------------------------------------------
199
217
// NavList.Group
200
218
201
- type NavListGroupProps = React . PropsWithChildren < {
219
+ type NavListGroupProps = {
202
220
children : React . ReactNode
203
221
title ?: string
204
- } >
222
+ } & SxProp
205
223
206
- // TODO: sx prop
207
224
// TODO: ref prop
208
- const Group = ( { title, children} : NavListGroupProps ) => {
225
+ const Group = ( { title, children, sx : sxProp = { } } : NavListGroupProps ) => {
209
226
return (
210
227
< >
211
228
{ /* Hide divider if the group is the first item in the list */ }
212
229
< ActionList . Divider sx = { { '&:first-child' : { display : 'none' } } } />
213
- < ActionList . Group title = { title } > { children } </ ActionList . Group >
230
+ < ActionList . Group title = { title } sx = { sxProp } >
231
+ { children }
232
+ </ ActionList . Group >
214
233
</ >
215
234
)
216
235
}
0 commit comments