-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Navigation): Complete controlled component related props
- Loading branch information
Showing
16 changed files
with
474 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
packages/fluent-ui.com/src/docs/components/Navigation/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
--- | ||
title: Navigation | ||
components: Navigation | ||
--- | ||
|
||
# Navigation | ||
|
||
<p class="description">The vertical navigation view control provides a collapsible upright navigation menu for top-level sections within the app.</p> | ||
|
||
## Controlled | ||
|
||
```jsx | ||
() => { | ||
const [activeId, setActiveId] = React.useState(1) | ||
function handleActiveId(id) { | ||
setActiveId(id) | ||
} | ||
return ( | ||
<Navigation height={600} value={activeId} onChange={handleActiveId}> | ||
<Navigation.Header> | ||
<Navigation.Item> | ||
<Icon type="GlobalNavigationButton" /> | ||
</Navigation.Item> | ||
</Navigation.Header> | ||
|
||
<Navigation.Item id={1}> | ||
<Icon type="Connected" /> | ||
<span>Option 1</span> | ||
</Navigation.Item> | ||
<Navigation.Item id={2}> | ||
<Icon type="Connected" /> | ||
<span>Option 2</span> | ||
</Navigation.Item> | ||
<Navigation.Item id={3}> | ||
<Icon type="Connected" /> | ||
<span>Option 3</span> | ||
</Navigation.Item> | ||
<Navigation.Item id={4}> | ||
<Icon type="Connected" /> | ||
<span>Option 4</span> | ||
</Navigation.Item> | ||
|
||
<Navigation.Footer> | ||
<Navigation.Item> | ||
<Icon type="Settings" /> | ||
<span>Settings</span> | ||
</Navigation.Item> | ||
</Navigation.Footer> | ||
</Navigation> | ||
) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import React, { ReactElement, ReactNode } from 'react' | ||
import Box from '../Box' | ||
|
||
interface ContentProps { | ||
children: ReactNode | ||
} | ||
|
||
const Content = ({ children }: ContentProps): ReactElement => ( | ||
<Box>{children}</Box> | ||
) | ||
|
||
export default Content |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React, { ReactElement, ReactNode } from 'react' | ||
import Box from '../Box' | ||
|
||
interface ItemProps { | ||
children: ReactNode | ||
} | ||
|
||
const Footer = ({ children }: ItemProps): ReactElement => <Box>{children}</Box> | ||
|
||
export default Footer |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import React, { ReactElement, ReactNode } from 'react' | ||
import Box from '../Box' | ||
|
||
interface ItemProps { | ||
children: ReactNode | ||
} | ||
|
||
const Header = ({ children }: ItemProps): ReactElement => <Box>{children}</Box> | ||
|
||
export default Header |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import React, { | ||
ReactElement, | ||
ReactNode, | ||
Children, | ||
ReactComponentElement, | ||
ReactChild, | ||
cloneElement, | ||
useContext, | ||
useEffect, | ||
useState | ||
} from 'react' | ||
import Box from '../Box' | ||
import { Icon } from '@fluent-ui/icons' | ||
import styled from '@xstyled/styled-components' | ||
import { th } from '@xstyled/system' | ||
import { NavigationContext } from './Navigation' | ||
import { useDispatch } from '../../hooks/useAction' | ||
|
||
export type ID = string | number | ||
|
||
interface ItemProps { | ||
id?: ID | ||
title?: string | ||
children: ReactNode | ||
} | ||
|
||
type Child = ReactComponentElement<typeof Icon> | ReactChild | any | ||
|
||
const StyledItemWrapper = styled.div` | ||
position: relative; | ||
max-height: 40px; | ||
height: 40px; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
padding: 12; | ||
box-sizing: border-box; | ||
transition: ${th.transition('navigation')}; | ||
&:hover { | ||
background-color: secondary; | ||
} | ||
&:active { | ||
background-color: primary; | ||
} | ||
` | ||
interface StyledItemActiveBarProps { | ||
active: boolean | ||
} | ||
const StyledItemActiveBar = styled.div<StyledItemActiveBarProps>` | ||
position: absolute; | ||
left: 0; | ||
top: 50%; | ||
background-color: accent; | ||
width: 6px; | ||
height: 24px; | ||
margin-top: -12px; | ||
transform: ${({ active }): string => | ||
active ? 'scale3d(1,1,1)' : 'scale3d(0,0,0)'}; | ||
transition: ${th.transition('navigation')}; | ||
` | ||
|
||
const Item = ({ id, children }: ItemProps): ReactElement => { | ||
const container: { | ||
icon: any | ||
content: any | ||
} = { | ||
icon: null, | ||
content: null | ||
} | ||
Children.forEach( | ||
children, | ||
(child: Child): void => { | ||
if (child.type && child.type.displayName === 'FIcon') { | ||
container.icon = cloneElement(child, { | ||
style: { width: 16, height: 16 } | ||
}) | ||
} else { | ||
container.content = cloneElement(child, { | ||
style: { fontSize: 14 } | ||
}) | ||
} | ||
} | ||
) | ||
|
||
// handle active item | ||
const activeID = useContext(NavigationContext) | ||
const dispatch = useDispatch({ type: 'navigation/handleActive', payload: id }) | ||
function handleItemClick(): void { | ||
dispatch() | ||
} | ||
const [active, setActive] = useState(false) | ||
useEffect((): void => { | ||
if (id) { | ||
if (activeID === id) setActive(true) | ||
else if (activeID && activeID !== id) setActive(false) | ||
} | ||
}, [activeID, id]) | ||
|
||
return ( | ||
<StyledItemWrapper onClick={handleItemClick}> | ||
{id && <StyledItemActiveBar active={active} />} | ||
<Box marginRight={12} height="100%"> | ||
{container.icon} | ||
</Box> | ||
<Box flex={1} display="flex" alignItems="center" overflow="hidden"> | ||
{container.content} | ||
</Box> | ||
</StyledItemWrapper> | ||
) | ||
} | ||
|
||
export default Item |
17 changes: 17 additions & 0 deletions
17
packages/fluent-ui/src/components/Navigation/Navigation.styled.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import styled from '@xstyled/styled-components' | ||
|
||
export const StyledHeader = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
` | ||
|
||
export const StyledFooter = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
` | ||
|
||
export const StyledContent = styled.div` | ||
flex: 1; | ||
display: flex; | ||
flex-direction: column; | ||
` |
Oops, something went wrong.