/* * Copyright 2017 Palantir Technologies, Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import classNames from "classnames"; import { ErrorIcon, type IconName, InfoSignIcon, type SVGIconProps, TickIcon, WarningSignIcon, } from "@blueprintjs/icons"; import { Classes, DISPLAYNAME_PREFIX, type HTMLDivProps, Intent, type IntentProps, type MaybeElement, type Props, Utils, } from "../../common"; import { H5 } from "../html/html"; import { Icon } from "../icon/icon"; /** This component also supports the full range of HTML `
` attributes. */ export interface CalloutProps extends IntentProps, Props, HTMLDivProps { /** Callout contents. */ children?: React.ReactNode; /** * Whether to use a compact appearance, which reduces the visual padding around callout content. */ compact?: boolean; /** * Name of a Blueprint UI icon (or an icon element) to render on the left side. * * If this prop is omitted or `undefined`, the `intent` prop will determine a default icon. * If this prop is explicitly `null`, no icon will be displayed (regardless of `intent`). */ icon?: IconName | MaybeElement; /** * Visual intent color to apply to background, title, and icon. * * Defining this prop also applies a default icon, if the `icon` prop is omitted. */ intent?: Intent; /** * Whether the callout should have a minimal appearance with no background color fill. * * @default false */ minimal?: boolean; /** * String content of optional title element. * * Due to a conflict with the HTML prop types, to provide JSX content simply * pass `

JSX title content

` as first `children` element instead of * using this prop (note uppercase tag name to use the Blueprint Heading * component). */ title?: string; } /** * Callout component. * * @see https://blueprintjs.com/docs/#core/components/callout */ export const Callout: React.FC = props => { const { className, children, icon, intent, title, compact, minimal = false, ...htmlProps } = props; const iconElement = renderIcon(icon, intent); const classes = classNames(Classes.CALLOUT, Classes.intentClass(intent), className, { [Classes.CALLOUT_HAS_BODY_CONTENT]: !Utils.isReactNodeEmpty(children), [Classes.CALLOUT_ICON]: iconElement != null, [Classes.COMPACT]: compact, [Classes.MINIMAL]: minimal, }); return (
{iconElement} {title &&
{title}
} {children}
); }; Callout.displayName = `${DISPLAYNAME_PREFIX}.Callout`; const renderIcon = (icon?: CalloutProps["icon"], intent?: Intent): IconName | MaybeElement => { // 1. no icon if (icon === null || icon === false) { return undefined; } const iconProps = { "aria-hidden": true, tabIndex: -1, } satisfies SVGIconProps; // 2. icon specified by name or as a custom SVG element if (icon !== undefined) { return ; } // 3. icon specified by intent prop switch (intent) { case Intent.DANGER: return ; case Intent.PRIMARY: return ; case Intent.WARNING: return ; case Intent.SUCCESS: return ; default: return undefined; } };