UNPKG

@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
/** @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;