Skip to content

Commit f3cef05

Browse files
author
chenyueban
committed
feat(Navigation): props expanded
1 parent b387416 commit f3cef05

6 files changed

Lines changed: 105 additions & 63 deletions

File tree

packages/fluent-ui.com/src/docs/components/Navigation/README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,54 @@ components: Navigation
5050
)
5151
}
5252
```
53+
54+
## expanded
55+
56+
```jsx
57+
() => {
58+
const [activeId, setActiveId] = React.useState(1)
59+
function handleActiveId(id) {
60+
setActiveId(id)
61+
}
62+
const [expanded, setExpanded] = React.useState(true)
63+
function handleExpanded() {
64+
setExpanded(e => !e)
65+
}
66+
return (
67+
<>
68+
<Button onClick={handleExpanded}>toggle</Button>
69+
<Navigation height={600} value={activeId} onChange={handleActiveId} expanded={expanded}>
70+
<Navigation.Header>
71+
<Navigation.Item>
72+
<Icon type="GlobalNavigationButton" />
73+
</Navigation.Item>
74+
</Navigation.Header>
75+
76+
<Navigation.Item id={1}>
77+
<Icon type="Connected" />
78+
<span>Option 1</span>
79+
</Navigation.Item>
80+
<Navigation.Item id={2}>
81+
<Icon type="Connected" />
82+
<span>Option 2</span>
83+
</Navigation.Item>
84+
<Navigation.Item id={3}>
85+
<Icon type="Connected" />
86+
<span>Option 3</span>
87+
</Navigation.Item>
88+
<Navigation.Item id={4}>
89+
<Icon type="Connected" />
90+
<span>Option 4</span>
91+
</Navigation.Item>
92+
93+
<Navigation.Footer>
94+
<Navigation.Item>
95+
<Icon type="Settings" />
96+
<span>Settings</span>
97+
</Navigation.Item>
98+
</Navigation.Footer>
99+
</Navigation>
100+
</>
101+
)
102+
}
103+
```

packages/fluent-ui/src/components/Box/style.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,6 @@ export interface StylesProps {
163163
*/
164164
opacity?: number
165165
overflow?: CSS.OverflowProperty
166-
Transition?: CSS.TransitionProperty
166+
transition?: CSS.TransitionProperty
167167
basics?: string
168168
}

packages/fluent-ui/src/components/Navigation/Item.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ const StyledItemActiveBar = styled.div<StyledItemActiveBarProps>`
5858
active ? 'scale3d(1,1,1)' : 'scale3d(0,0,0)'};
5959
transition: ${th.transition('navigation')};
6060
`
61+
const StyledItemIconWrapper = styled.div<{ expanded: boolean }>`
62+
margin-right: ${({ expanded }): string => (expanded ? '12px' : '0px')};
63+
height: 100%;
64+
transition: ${th.transition('navigation')};
65+
`
66+
const StyledItemTextWrapper = styled.div<{ expanded: boolean }>`
67+
width: ${({ expanded }): string => (expanded ? 'auto' : '0px')};
68+
opacity: ${({ expanded }): number => (expanded ? 1 : 0)};
69+
flex: 1;
70+
display: flex;
71+
align-items: center;
72+
overflow: hidden;
73+
white-space: nowrap;
74+
transition: ${th.transition('navigation')};
75+
`
6176

6277
const Item = ({ id, children }: ItemProps): ReactElement => {
6378
const container: {
@@ -83,7 +98,7 @@ const Item = ({ id, children }: ItemProps): ReactElement => {
8398
)
8499

85100
// handle active item
86-
const activeID = useContext(NavigationContext)
101+
const { value: activeID, expanded } = useContext(NavigationContext)
87102
const dispatch = useDispatch({ type: 'navigation/handleActive', payload: id })
88103
function handleItemClick(): void {
89104
dispatch()
@@ -99,12 +114,12 @@ const Item = ({ id, children }: ItemProps): ReactElement => {
99114
return (
100115
<StyledItemWrapper onClick={handleItemClick}>
101116
{id && <StyledItemActiveBar active={active} />}
102-
<Box marginRight={12} height="100%">
117+
<StyledItemIconWrapper expanded={expanded}>
103118
{container.icon}
104-
</Box>
105-
<Box flex={1} display="flex" alignItems="center" overflow="hidden">
119+
</StyledItemIconWrapper>
120+
<StyledItemTextWrapper expanded={expanded}>
106121
{container.content}
107-
</Box>
122+
</StyledItemTextWrapper>
108123
</StyledItemWrapper>
109124
)
110125
}

packages/fluent-ui/src/components/Navigation/Navigation.styled.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
11
import styled from '@xstyled/styled-components'
2+
import { th } from '@xstyled/system'
3+
4+
export const StyledContainer = (styled as any).box`
5+
display: flex;
6+
flex-direction: column;
7+
justify-content: space-between;
8+
background-color: ${({ backgroundColor }: any): string => backgroundColor};
9+
max-width: ${({ expanded }: any): string => (expanded ? '260px' : '40px')};
10+
transition: ${th.transition('navigation')};
11+
`
212

313
export const StyledHeader = styled.div`
414
display: flex;

packages/fluent-ui/src/components/Navigation/Navigation.tsx

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,23 @@ import React, {
66
ReactComponentElement,
77
createContext
88
} from 'react'
9-
import Box from '../Box'
109
import Item, { ID } from './Item'
1110
import { BoxProps } from '../Box/Box'
1211
import { ThemeProps } from '../../theme'
1312
import Header from './Header'
1413
import Footer from './Footer'
1514
import Content from './Content'
16-
import { StyledHeader, StyledFooter, StyledContent } from './Navigation.styled'
15+
import {
16+
StyledHeader,
17+
StyledFooter,
18+
StyledContent,
19+
StyledContainer
20+
} from './Navigation.styled'
1721
import { useAction } from '../../hooks/useAction'
1822

1923
interface NavigationProps extends Omit<BoxProps, 'onChange'>, ThemeProps {
2024
response?: boolean
25+
expanded?: boolean
2126
value?: ID
2227
onChange?: (id: ID) => void
2328
}
@@ -41,11 +46,14 @@ type Child =
4146
| ReactComponentElement<typeof Content>
4247
| any
4348

44-
export const NavigationContext = createContext<ID>('')
49+
export const NavigationContext = createContext<{
50+
value: ID
51+
expanded: boolean
52+
}>({ value: '', expanded: true })
4553

4654
const Navigation: NavigationType = forwardRef<HTMLDivElement, NavigationProps>(
4755
(
48-
{ value, onChange, children, ...rest }: NavigationProps,
56+
{ expanded, value, onChange, children, ...rest }: NavigationProps,
4957
ref
5058
): ReactElement => {
5159
const container: Container = {
@@ -66,6 +74,7 @@ const Navigation: NavigationType = forwardRef<HTMLDivElement, NavigationProps>(
6674
}
6775
)
6876

77+
// handle active item
6978
useAction(
7079
'navigation/handleActive',
7180
(id): void => {
@@ -74,20 +83,17 @@ const Navigation: NavigationType = forwardRef<HTMLDivElement, NavigationProps>(
7483
[value]
7584
)
7685

86+
const contextValue = {
87+
value: value as ID,
88+
expanded: expanded as boolean
89+
}
7790
return (
78-
<NavigationContext.Provider value={value as ID}>
79-
<Box
80-
ref={ref}
81-
maxWidth={260}
82-
display="flex"
83-
flexDirection="column"
84-
justifyContent="space-between"
85-
{...rest}
86-
>
91+
<NavigationContext.Provider value={contextValue}>
92+
<StyledContainer expanded={expanded as boolean} ref={ref} {...rest}>
8793
<StyledHeader>{container.header}</StyledHeader>
8894
<StyledContent>{container.content}</StyledContent>
8995
<StyledFooter>{container.footer}</StyledFooter>
90-
</Box>
96+
</StyledContainer>
9197
</NavigationContext.Provider>
9298
)
9399
}
@@ -101,7 +107,8 @@ Navigation.Item = Item
101107
Navigation.displayName = 'FNavigation'
102108

103109
Navigation.defaultProps = {
104-
backgroundColor: '#e6e6e6'
110+
backgroundColor: '#e6e6e6',
111+
expanded: true
105112
}
106113

107114
export default Navigation

packages/fluent-ui/src/types/index.d.ts

Lines changed: 1 addition & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,8 @@
11
declare module '@xstyled/styled-components' {
2-
import baseStyled, {
3-
ThemedStyledFunction,
4-
AnyStyledComponent,
5-
StyledComponent
6-
} from 'styled-components'
2+
import styled, { ThemedStyledFunction } from 'styled-components'
73
import { ReactElement } from 'react'
84
export * from 'styled-components'
9-
type AnyIfEmpty<T extends object> = keyof T extends never ? any : T
105

11-
type StyledComponentInnerAttrs<
12-
C extends AnyStyledComponent
13-
> = C extends StyledComponent<any, any, any, infer A> ? A : never
14-
type StyledComponentInnerOtherProps<C extends AnyStyledComponent> = C extends
15-
| StyledComponent<any, any, infer O, any>
16-
| StyledComponent<any, any, infer O>
17-
? O
18-
: never
19-
type StyledComponentInnerComponent<
20-
C extends React.ComponentType<any>
21-
> = C extends
22-
| StyledComponent<infer I, any, any, any>
23-
| StyledComponent<infer I, any, any>
24-
? I
25-
: C
26-
type ThemedStyledComponentFactories<T extends object> = {
27-
[TTag in keyof JSX.IntrinsicElements]: ThemedStyledFunction<TTag, T>
28-
}
29-
interface ThemedBaseStyledInterface<T extends object>
30-
extends ThemedStyledComponentFactories<T> {
31-
<C extends AnyStyledComponent>(component: C): ThemedStyledFunction<
32-
StyledComponentInnerComponent<C>,
33-
T,
34-
StyledComponentInnerOtherProps<C>,
35-
StyledComponentInnerAttrs<C>
36-
>
37-
<C extends keyof JSX.IntrinsicElements | React.ComponentType<any>>(
38-
component: C
39-
): ThemedStyledFunction<C, T>
40-
box(component: 'div'): ThemedStyledFunction<'div', T>
41-
}
42-
export type ThemedStyledInterface<
43-
T extends object
44-
> = ThemedBaseStyledInterface<AnyIfEmpty<T>>
45-
export type StyledInterface = ThemedStyledInterface<{}>
46-
const styled: StyledInterface
476
export const Box: ThemedStyledFunction<'div', any>
487
export default styled
498
}

0 commit comments

Comments
 (0)