Changeset View
Standalone View
web/sidebar/navigation-panel.react.js
// @flow | // @flow | ||||
import classNames from 'classnames'; | import classNames from 'classnames'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import type { AppState } from '../redux/redux-setup.js'; | import type { AppState } from '../redux/redux-setup.js'; | ||||
import { useSelector } from '../redux/redux-utils'; | import { useSelector } from '../redux/redux-utils'; | ||||
import css from './left-layout-aside.css'; | import horizontalCSS from '../topbar/topbar.css'; | ||||
import verticalCSS from './left-layout-aside.css'; | |||||
type NavigationPanelItemProps = { | type NavigationPanelItemProps = { | ||||
+tab: string, | +tab: string, | ||||
+children: React.Node, | +children: React.Node, | ||||
}; | }; | ||||
function NavigationPanelItem(props: NavigationPanelItemProps): React.Node { | function NavigationPanelItem(props: NavigationPanelItemProps): React.Node { | ||||
const { children } = props; | const { children } = props; | ||||
return children; | return children; | ||||
} | } | ||||
type NavigationPanelContainerProps<T> = { | type NavigationPanelContainerProps<T> = { | ||||
+tabSelector: AppState => T, | +tabSelector: AppState => T, | ||||
+children: React.ChildrenArray<?React.Element<typeof NavigationPanelItem>>, | +children: React.ChildrenArray<?React.Element<typeof NavigationPanelItem>>, | ||||
+horizontal?: boolean, | |||||
}; | }; | ||||
function NavigationPanelContainer<T>( | function NavigationPanelContainer<T>( | ||||
props: NavigationPanelContainerProps<T>, | props: NavigationPanelContainerProps<T>, | ||||
): React.Node { | ): React.Node { | ||||
const { children, tabSelector } = props; | const { children, tabSelector, horizontal = false } = props; | ||||
const currentTab = useSelector(tabSelector); | const currentTab = useSelector(tabSelector); | ||||
const css = horizontal ? horizontalCSS : verticalCSS; | |||||
const items = React.useMemo( | const items = React.useMemo( | ||||
() => | () => | ||||
React.Children.map(children, child => { | React.Children.map(children, child => { | ||||
if (!child) { | if (!child) { | ||||
return null; | return null; | ||||
} | } | ||||
return ( | return ( | ||||
<div | <div | ||||
key={child.props.tab} | key={child.props.tab} | ||||
className={classNames({ | className={classNames({ | ||||
[css.current_tab]: currentTab === child.props.tab, | [css.current_tab]: currentTab === child.props.tab, | ||||
})} | })} | ||||
> | > | ||||
{child} | {child} | ||||
</div> | </div> | ||||
); | ); | ||||
}), | }), | ||||
[children, currentTab], | [children, css.current_tab, currentTab], | ||||
bartek: I'm not sure about this one. Will this class name be changed when switching the `horizontal`… | |||||
inkaAuthorUnsubmitted Done Inline Actions(eslint says to do it, and even if it's not needed, I don't think it hurts) inka: (eslint says to do it, and even if it's not needed, I don't think it hurts)
We change the css… | |||||
bartekUnsubmitted Not Done Inline Actions
This is convincing enough, thanks ;)
The class itself changes, but this memo depends only on its name, which should be constant (unless it's hashed), this is why I asked initially ;)
Yes, but we shouldn't depend on the "immutability by design" of this prop - it isn't supposed to be mutated now, but it can be in the future and nothing's blocking it bartek: > eslint says to do it
This is convincing enough, thanks ;)
Now I recall that this dependency… | |||||
); | ); | ||||
return <div className={css.navigationPanelContainer}>{items}</div>; | return <div className={css.navigationPanelContainer}>{items}</div>; | ||||
} | } | ||||
const NavigationPanel = { | const NavigationPanel = { | ||||
Item: NavigationPanelItem, | Item: NavigationPanelItem, | ||||
Container: NavigationPanelContainer, | Container: NavigationPanelContainer, | ||||
}; | }; | ||||
export default NavigationPanel; | export default NavigationPanel; |
I'm not sure about this one. Will this class name be changed when switching the horizontal prop?