/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. * * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch B.V. licenses this file to you 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 React, { AriaAttributes, Fragment, FunctionComponent, HTMLAttributes, MouseEventHandler, ReactNode, } from 'react'; import classNames from 'classnames'; import { CommonProps, ExclusiveUnion, keysOf } from '../../common'; import { getSecureRelForTarget } from '../../../services'; import { OuiToolTip, ToolTipPositions } from '../../tool_tip'; import { OuiIcon, IconType } from '../../icon'; const colorToClassMap = { subdued: 'ouiBetaBadge--subdued', hollow: 'ouiBetaBadge--hollow', }; export const COLORS: BetaBadgeColor[] = keysOf(colorToClassMap); export type BetaBadgeColor = keyof typeof colorToClassMap; export type BetaBadgeSize = 's' | 'm'; export const sizeToClassMap: { [size in BetaBadgeSize]: string | null } = { s: 'ouiBetaBadge--small', m: null, }; export const SIZES = keysOf(sizeToClassMap); type WithButtonProps = { /** * Will apply an onclick to the badge itself */ onClick?: MouseEventHandler; /** * Aria label applied to the onClick button */ onClickAriaLabel?: AriaAttributes['aria-label']; } & Omit, 'onClick' | 'color'>; type WithAnchorProps = { href: string; target?: string; rel?: string; } & Omit, 'href' | 'color' | 'onClick'>; type WithSpanProps = Omit< HTMLAttributes, 'onClick' | 'color' | 'title' >; // `label` prop can be a `ReactNode` only if `title` or `tooltipContent` is provided type LabelAsNode = ExclusiveUnion< { title: string; tooltipContent?: ReactNode; }, { tooltipContent: ReactNode; title?: string; } > & { label: ReactNode; }; interface LabelAsString { /** * One word label like "Beta" or "Lab" */ label: string; } type BadgeProps = { /** * Supply an icon type if the badge should just be an icon */ iconType?: IconType; /** * One word label like "Beta" or "Lab" */ label: ReactNode; /** * Content for the tooltip */ tooltipContent?: ReactNode; /** * Custom position of the tooltip */ tooltipPosition?: ToolTipPositions; /** * Optional title will be supplied as tooltip title or title attribute * otherwise the label will be used */ title?: string; /** * Accepts subdued and hollow. */ color?: BetaBadgeColor; size?: BetaBadgeSize; } & ExclusiveUnion; export type OuiBetaBadgeProps = CommonProps & ExclusiveUnion< ExclusiveUnion, WithSpanProps > & BadgeProps; export const OuiBetaBadge: FunctionComponent = ({ className, label, color = 'hollow', tooltipContent, tooltipPosition = 'top', title, iconType, onClick, onClickAriaLabel, href, rel, target, size = 'm', ...rest }) => { let singleLetter = false; if (typeof label === 'string' && label.length === 1) { singleLetter = true; } const classes = classNames( 'ouiBetaBadge', { 'ouiBetaBadge--iconOnly': iconType, 'ouiBetaBadge--singleLetter': singleLetter, 'ouiBetaBadge-isClickable': onClick || href, }, colorToClassMap[color], sizeToClassMap[size], className ); let icon: JSX.Element | undefined; if (iconType) { icon = (