UNPKG

@fluent-windows/core

Version:

React components that inspired by Microsoft's Fluent Design System.

146 lines (137 loc) 4.36 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import * as React from 'react'; import classNames from 'classnames'; import { createUseStyles } from '@fluent-windows/styles'; import { styles } from './Navigation.styled'; import { NavigationPropTypes } from './Navigation.type'; import { useReveal } from '@fluent-windows/hooks'; // TODO treeShaking import { omit } from '../utils'; import Header from './components/Header'; import Footer from './components/Footer'; import Content from './components/Content'; import Box from '../Box'; export const NavigationContext = React.createContext({ value: '', onChange: () => {}, expanded: true, reveal: false, acrylic: false, horizontal: false }); export const name = 'Navigation'; const useStyles = createUseStyles(styles, { name }); const Navigation = React.forwardRef((props, ref) => { const { as = 'div', className: classNameProp, horizontal = false, expanded = true, acrylic = false, reveal = false, value, onChange, children, ...rest } = props; const container = React.useMemo(() => React.Children.toArray(children).reduce((acc, cur) => { if (cur.type && cur.type.displayName === 'FNavigationHeader') { return { ...acc, header: [...acc.header, cur] }; } else if (cur.type && cur.type.displayName === 'FNavigationFooter') { return { ...acc, footer: [...acc.footer, cur] }; } return { ...acc, content: [...acc.content, cur] }; }, { header: [], footer: [], content: [] }), [children]); const _reveal = React.useMemo(() => acrylic ? false : reveal, [acrylic, reveal]); const [RevealWrapper] = useReveal(66); const revealHeader = React.useMemo(() => container.header.map((child, i) => React.createElement(RevealWrapper, { key: i }, child)), [] // eslint-disable-line ); const revealContent = React.useMemo(() => container.content.map((child, i) => { if (child.type && child.type.displayName === 'FItem') { return React.createElement(RevealWrapper, { key: i }, child); } return child; }), [] // eslint-disable-line ); const revealFooter = React.useMemo(() => container.footer.map((child, i) => React.createElement(RevealWrapper, { key: i }, child)), [] // eslint-disable-line ); const contextValue = { value: value, onChange: onChange, expanded: expanded, reveal: _reveal, acrylic: acrylic, horizontal: horizontal }; const others = omit(rest, ['backgroundColor', 'color']); const classes = useStyles(props); const className = classNames(classes.root, { [classes.horizontal]: horizontal, [classes.expanded]: expanded }, classNameProp); const headerClassName = classNames(classes.header, { [classes.headerHorizontal]: horizontal }); const contentClassName = classNames(classes.content, { [classes.contentHorizontal]: horizontal }); const footerClassName = classNames(classes.footer, { [classes.footerHorizontal]: horizontal }); return React.createElement(Box, _extends({ className: className, as: as, ref: ref, acrylic: acrylic, backgroundColor: "standard.light2" }, others), React.createElement(NavigationContext.Provider, { value: contextValue }, React.createElement(Box, { className: headerClassName }, _reveal ? revealHeader : container.header), React.createElement(Box, { className: contentClassName }, _reveal ? revealContent : container.content), React.createElement(Box, { className: footerClassName }, _reveal ? revealFooter : container.footer))); }); Object.defineProperty(Navigation, 'Header', { get() { return Header; } }); Object.defineProperty(Navigation, 'Footer', { get() { return Footer; } }); Object.defineProperty(Navigation, 'Content', { get() { return Content; } }); Navigation.displayName = `F${name}`; Navigation.propTypes = NavigationPropTypes; Navigation.defaultProps = { horizontal: false, expanded: true, acrylic: false, reveal: false }; export default Navigation;