@atlaskit/modal-dialog
Version:
A modal dialog displays content that requires user interaction, in a layer above the page.
105 lines (103 loc) • 3.22 kB
JavaScript
/** @jsx jsx */
import { css, jsx } from '@emotion/react';
import ErrorIcon from '@atlaskit/icon/glyph/error';
import WarningIcon from '@atlaskit/icon/glyph/warning';
import { useModal } from './hooks';
import { iconColor, titleIconMargin } from './internal/constants';
const fontSize = 20;
const lineHeight = 1;
const adjustedLineHeight = 1.2;
const titleStyles = css({
display: 'flex',
minWidth: 0,
margin: "var(--ds-space-0, 0px)",
alignItems: 'center',
fontSize: "var(--ds-font-size-300, 20px)",
fontStyle: 'inherit',
fontWeight: "var(--ds-font-weight-medium, 500)",
letterSpacing: `-0.008em`,
lineHeight: lineHeight
});
const textStyles = css({
minWidth: 0,
/**
* This ensures that the element fills the whole header space
* and its content does not overflow (since flex items don't
* shrink past its content size by default).
*/
flex: '1 1 auto',
wordWrap: 'break-word'
});
const iconStyles = css({
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
marginRight: `${titleIconMargin}px`,
flex: '0 0 auto',
alignSelf: 'start'
});
/**
* When the title is truncated (not multi-line), we adjust the
* line height to avoid cropping the descenders. This removes
* the extra spacing that we get from that adjustment.
*/
const lineHeightOffset = fontSize - fontSize * adjustedLineHeight;
const truncatedTextStyles = css({
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
marginTop: `${lineHeightOffset / 2}px`,
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
marginBottom: `${lineHeightOffset / 2}px`,
lineHeight: adjustedLineHeight,
overflow: 'hidden',
textOverflow: 'ellipsis',
whiteSpace: 'nowrap'
});
const truncatedTextIconStyles = css({
// eslint-disable-next-line @atlaskit/design-system/ensure-design-token-usage-spacing
marginBottom: `${lineHeightOffset / 2}px`,
lineHeight: 1.2
});
const TitleIcon = ({
appearance,
isMultiline
}) => {
const Icon = appearance === 'danger' ? ErrorIcon : WarningIcon;
return jsx("span", {
css: [iconStyles, !isMultiline && truncatedTextIconStyles]
}, jsx(Icon, {
label: `${appearance} icon`,
primaryColor: iconColor[appearance]
}));
};
/**
* __Modal title__
*
* A modal title is used to display a title within a modal.
*
* - [Examples](https://atlassian.design/components/modal-dialog/examples)
* - [Code](https://atlassian.design/components/modal-dialog/code)
* - [Usage](https://atlassian.design/components/modal-dialog/usage)
*/
const ModalTitle = props => {
const {
appearance,
children,
isMultiline = true,
testId: userDefinedTestId
} = props;
const {
titleId,
testId: modalTestId
} = useModal();
const testId = userDefinedTestId || modalTestId && `${modalTestId}--title`;
return jsx("h1", {
css: titleStyles,
"data-testid": testId
}, appearance && jsx(TitleIcon, {
appearance: appearance,
isMultiline: isMultiline
}), jsx("span", {
id: titleId,
css: [textStyles, !isMultiline && truncatedTextStyles],
"data-testid": testId && `${testId}-text`
}, children));
};
export default ModalTitle;