Files
grafana/public/app/core/components/Upgrade/UpgradeBox.tsx
Josh Hunt 07266aa983 Rewrite old useStyles2 pattern to use new pattern (#76136)
* Rewrite old useStyles2 pattern to use new pattern

* fix lint from used imports
2023-10-09 10:49:08 +01:00

267 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { css, cx } from '@emotion/css';
import React, { HTMLAttributes, useEffect } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { reportExperimentView } from '@grafana/runtime/src';
import { Button, Icon, LinkButton, useStyles2 } from '@grafana/ui';
type ComponentSize = 'sm' | 'md';
export interface Props extends HTMLAttributes<HTMLOrSVGElement> {
featureName: string;
size?: ComponentSize;
text?: string;
eventVariant?: string;
featureId: string;
}
export const UpgradeBox = ({
featureName,
className,
children,
text,
featureId,
eventVariant = '',
size = 'md',
...htmlProps
}: Props) => {
const styles = useStyles2(getUpgradeBoxStyles, size);
useEffect(() => {
reportExperimentView(`feature-highlights-${featureId}`, 'test', eventVariant);
}, [eventVariant, featureId]);
return (
<div className={cx(styles.box, className)} {...htmlProps}>
<Icon name={'rocket'} className={styles.icon} />
<div className={styles.inner}>
<p className={styles.text}>
Youve discovered a Pro feature! {text || `Get the Grafana Pro plan to access ${featureName}.`}
</p>
<LinkButton
variant="secondary"
size={size}
className={styles.button}
href="https://grafana.com/profile/org/subscription"
target="__blank"
rel="noopener noreferrer"
>
Upgrade
</LinkButton>
</div>
</div>
);
};
const getUpgradeBoxStyles = (theme: GrafanaTheme2, size: ComponentSize) => {
const borderRadius = theme.shape.borderRadius(2);
const fontBase = size === 'md' ? 'body' : 'bodySmall';
return {
box: css`
display: flex;
align-items: center;
position: relative;
border-radius: ${borderRadius};
background: ${theme.colors.success.transparent};
padding: ${theme.spacing(2)};
color: ${theme.colors.success.text};
font-size: ${theme.typography[fontBase].fontSize};
text-align: left;
line-height: 16px;
margin: ${theme.spacing(0, 'auto', 3, 'auto')};
max-width: ${theme.breakpoints.values.xxl}px;
width: 100%;
`,
inner: css`
display: flex;
align-items: center;
width: 100%;
justify-content: space-between;
`,
text: css`
margin: 0;
`,
button: css`
background-color: ${theme.colors.success.main};
font-weight: ${theme.typography.fontWeightLight};
color: white;
&:hover {
background-color: ${theme.colors.success.main};
}
&:focus-visible {
box-shadow: none;
color: ${theme.colors.text.primary};
outline: 2px solid ${theme.colors.primary.main};
}
`,
icon: css`
margin: ${theme.spacing(0.5, 1, 0.5, 0.5)};
`,
};
};
export interface UpgradeContentProps {
image: string;
featureUrl?: string;
featureName: string;
description?: string;
listItems: string[];
caption?: string;
action?: {
text: string;
link?: string;
onClick?: () => void;
};
}
export const UpgradeContent = ({
listItems,
image,
featureUrl,
featureName,
description,
caption,
action,
}: UpgradeContentProps) => {
const styles = useStyles2(getUpgradeContentStyles);
return (
<div className={styles.container}>
<div className={styles.content}>
<h3 className={styles.title}>Get started with {featureName}</h3>
{description && <h6 className={styles.description}>{description}</h6>}
<ul className={styles.list}>
{listItems.map((item, index) => (
<li key={index}>
<Icon name={'check'} size={'xl'} className={styles.icon} /> {item}
</li>
))}
</ul>
{action?.link && (
<LinkButton variant={'primary'} href={action.link}>
{action.text}
</LinkButton>
)}
{action?.onClick && (
<Button variant={'primary'} onClick={action.onClick}>
{action.text}
</Button>
)}
{featureUrl && (
<LinkButton fill={'text'} href={featureUrl} className={styles.link} target="_blank" rel="noreferrer noopener">
Learn more
</LinkButton>
)}
</div>
<div className={styles.media}>
<img src={getImgUrl(image)} alt={'Feature screenshot'} />
{caption && <p className={styles.caption}>{caption}</p>}
</div>
</div>
);
};
const getUpgradeContentStyles = (theme: GrafanaTheme2) => {
return {
container: css`
display: flex;
justify-content: space-between;
`,
content: css`
width: 45%;
margin-right: ${theme.spacing(4)};
`,
media: css`
width: 55%;
img {
width: 100%;
}
`,
title: css`
color: ${theme.colors.text.maxContrast};
`,
description: css`
color: ${theme.colors.text.primary};
font-weight: ${theme.typography.fontWeightLight};
`,
list: css`
list-style: none;
margin: ${theme.spacing(4, 0, 2, 0)};
li {
display: flex;
align-items: flex-start;
color: ${theme.colors.text.primary};
padding: ${theme.spacing(1, 0)};
}
`,
icon: css`
color: ${theme.colors.success.main};
margin-right: ${theme.spacing(1)};
`,
link: css`
margin-left: ${theme.spacing(2)};
`,
caption: css`
font-weight: ${theme.typography.fontWeightLight};
margin: ${theme.spacing(1, 0, 0)};
`,
};
};
export const UpgradeContentVertical = ({
featureName,
description,
featureUrl,
image,
}: Omit<UpgradeContentProps, 'listItems' | 'caption'>) => {
const styles = useStyles2(getContentVerticalStyles);
return (
<div className={styles.container}>
<h3 className={styles.title}>Get started with {featureName}</h3>
{description && <h6 className={styles.description}>{description}</h6>}
<LinkButton fill={'text'} href={featureUrl} target="_blank" rel="noreferrer noopener">
Learn more
</LinkButton>
<div className={styles.media}>
<img src={getImgUrl(image)} alt={'Feature screenshot'} />
</div>
</div>
);
};
const getContentVerticalStyles = (theme: GrafanaTheme2) => {
return {
container: css`
overflow: auto;
height: 100%;
`,
title: css`
color: ${theme.colors.text.maxContrast};
`,
description: css`
color: ${theme.colors.text.primary};
font-weight: ${theme.typography.fontWeightLight};
`,
media: css`
width: 100%;
margin-top: ${theme.spacing(2)};
img {
width: 100%;
}
`,
};
};
const getImgUrl = (urlOrId: string) => {
if (urlOrId.startsWith('http')) {
return urlOrId;
}
return '/public/img/enterprise/highlights/' + urlOrId;
};