205 lines
4.9 KiB
JavaScript
205 lines
4.9 KiB
JavaScript
import React from 'react';
|
|
import { Broadcast, Subscriber } from 'joy-react-broadcast';
|
|
import PropTypes from 'prop-types';
|
|
import is, { isNot, isOr } from 'styled-is';
|
|
import isBoolean from 'lodash.isboolean';
|
|
import remcalc from 'remcalc';
|
|
|
|
import Baseline from '../baseline';
|
|
import Card, { BaseCard } from './card';
|
|
|
|
const BaseHeader = BaseCard.extend`
|
|
flex-direction: row;
|
|
z-index: 1;
|
|
line-height: ${remcalc(24)};
|
|
height: auto;
|
|
|
|
margin: ${remcalc(-1)} ${remcalc(-1)} 0 ${remcalc(-1)};
|
|
|
|
${is('parentCollapsed')`
|
|
margin: ${remcalc(-1)};
|
|
box-shadow: none;
|
|
`};
|
|
|
|
${isNot('secondary', 'tertiary')`
|
|
${is('transparent')`
|
|
color: ${props => props.theme.text};
|
|
-webkit-text-fill-color: currentcolor;
|
|
`};
|
|
`};
|
|
|
|
${is('disabled')`
|
|
color: ${props => props.theme.text};
|
|
-webkit-text-fill-color: currentcolor;
|
|
border-color: ${props => props.theme.grey};
|
|
box-shadow: none;
|
|
`};
|
|
|
|
button {
|
|
margin-bottom: 0;
|
|
margin-top: 0;
|
|
}
|
|
`;
|
|
|
|
const BaseBox = BaseCard.extend`
|
|
width: ${remcalc(49)};
|
|
min-width: ${remcalc(49)};
|
|
min-height: ${remcalc(46)};
|
|
|
|
display: inline-flex;
|
|
flex: 0 0 auto;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
background-color: transparent;
|
|
border-width: 0;
|
|
border-radius: 0;
|
|
box-shadow: none;
|
|
|
|
${is('border')`
|
|
border-right-width: ${props => (props.border === 'right' ? remcalc(1) : 0)};
|
|
border-left-width: ${props => (props.border === 'left' ? remcalc(1) : 0)};
|
|
`};
|
|
|
|
${is('actionable', 'secondary')`
|
|
&:hover {
|
|
background-color: ${props => props.theme.primaryHover};
|
|
}
|
|
`};
|
|
|
|
${is('disabled')`
|
|
color: ${props => props.theme.text};
|
|
-webkit-text-fill-color: currentcolor;
|
|
border-color: ${props => props.theme.grey};
|
|
box-shadow: none;
|
|
|
|
&:hover {
|
|
background-color: transparent;
|
|
}
|
|
`};
|
|
`;
|
|
|
|
const BaseMeta = BaseCard.extend`
|
|
box-sizing: border-box;
|
|
min-height: ${remcalc(47)};
|
|
width: auto;
|
|
height: auto;
|
|
padding: ${remcalc(12)};
|
|
|
|
display: inline-flex;
|
|
flex: 1 1 auto;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
|
|
align-items: stretch;
|
|
align-content: stretch;
|
|
overflow: hidden;
|
|
|
|
background-color: transparent;
|
|
border-width: 0;
|
|
box-shadow: none;
|
|
color: inherit;
|
|
`;
|
|
|
|
export const Box = ({ children, border, actionable, ...rest }) => {
|
|
const render = ({ secondary, transparent, parentCollapsed, ...value }) => {
|
|
// if parent is collapsed, show border
|
|
// if parent is not collapsed, only if this is secondary and not transparent
|
|
const showBorder = parentCollapsed || (secondary && !transparent);
|
|
const newBorder = showBorder && border;
|
|
|
|
return (
|
|
<BaseBox
|
|
{...value}
|
|
{...rest}
|
|
name="card-header-box"
|
|
border={newBorder}
|
|
secondary={secondary}
|
|
transparent={transparent}
|
|
parentCollapsed={parentCollapsed}
|
|
actionable={actionable}
|
|
collapsed
|
|
>
|
|
{children}
|
|
</BaseBox>
|
|
);
|
|
};
|
|
|
|
return <Subscriber channel="card">{render}</Subscriber>;
|
|
};
|
|
|
|
Box.propTypes = {
|
|
...Card.propTypes,
|
|
children: PropTypes.node,
|
|
border: PropTypes.oneOf(['left', 'right'])
|
|
};
|
|
|
|
Box.defaultProps = {
|
|
...Card.defaultProps,
|
|
children: null,
|
|
border: null
|
|
};
|
|
|
|
export const Meta = ({ children, ...rest }) => (
|
|
<Subscriber channel="card">
|
|
{value => (
|
|
<BaseMeta {...rest} {...value} name="card-header-meta" collapsed>
|
|
{children}
|
|
</BaseMeta>
|
|
)}
|
|
</Subscriber>
|
|
);
|
|
|
|
const Header = ({ children, transparent, shadow, ...rest }) => {
|
|
const render = ({ secondary, tertiary, collapsed, actionable, ...value }) => {
|
|
const parentPrimary = !secondary && !tertiary;
|
|
// if secondary is hardcoded, use that
|
|
// if transparent and parent is secondary, keep seconday
|
|
// if parent is secondary, keep being secondary or
|
|
// if parent is primary, become secondary
|
|
const isSecondary = isBoolean(rest.secondary)
|
|
? rest.secondary
|
|
: transparent ? secondary : secondary || parentPrimary;
|
|
// if parent is primary, don't become transparent
|
|
const isTransparent = transparent || secondary || tertiary;
|
|
|
|
const newValue = {
|
|
...value,
|
|
parentCollapsed: collapsed,
|
|
secondary: isSecondary,
|
|
tertiary: isBoolean(rest.tertiary) ? rest.tertiary : tertiary,
|
|
actionable: isBoolean(rest.actionable) ? rest.actionable : actionable,
|
|
transparent: isTransparent,
|
|
collapsed: true,
|
|
shadow: Boolean(shadow)
|
|
};
|
|
|
|
return (
|
|
<Broadcast channel="card" value={newValue}>
|
|
<BaseHeader
|
|
{...rest}
|
|
{...newValue}
|
|
name="card-header"
|
|
parentCollapsed={collapsed}
|
|
shadow={shadow}
|
|
>
|
|
{children}
|
|
</BaseHeader>
|
|
</Broadcast>
|
|
);
|
|
};
|
|
|
|
return <Subscriber channel="card">{render}</Subscriber>;
|
|
};
|
|
|
|
Header.propTypes = {
|
|
children: PropTypes.node
|
|
};
|
|
|
|
Header.defaultProps = {
|
|
children: null
|
|
};
|
|
|
|
export default Baseline(Header);
|