@fluent-windows/core
Version:
React components that inspired by Microsoft's Fluent Design System.
146 lines (137 loc) • 4.36 kB
JavaScript
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;