|
1 |
| -import type { Interpolation, Theme } from "@emotion/react"; |
2 |
| -import Link from "@mui/material/Link"; |
3 |
| -import { visuallyHidden } from "@mui/utils"; |
4 |
| -import { HelpTooltipContent } from "components/HelpTooltip/HelpTooltip"; |
5 |
| -import { Popover, PopoverTrigger } from "components/deprecated/Popover/Popover"; |
| 1 | +import { Link } from "components/Link/Link"; |
| 2 | +import { |
| 3 | + Tooltip, |
| 4 | + TooltipContent, |
| 5 | + TooltipProvider, |
| 6 | + TooltipTrigger, |
| 7 | +} from "components/Tooltip/Tooltip"; |
6 | 8 | import type { FC, HTMLAttributes, ReactNode } from "react";
|
| 9 | +import { cn } from "utils/cn"; |
7 | 10 | import { docs } from "utils/docs";
|
8 | 11 |
|
9 | 12 | /**
|
10 | 13 | * All types of feature that we are currently supporting. Defined as record to
|
11 | 14 | * ensure that we can't accidentally make typos when writing the badge text.
|
12 | 15 | */
|
13 | 16 | export const featureStageBadgeTypes = {
|
| 17 | + early_access: "early access", |
14 | 18 | beta: "beta",
|
15 |
| - experimental: "experimental", |
16 | 19 | } as const satisfies Record<string, ReactNode>;
|
17 | 20 |
|
18 | 21 | type FeatureStageBadgeProps = Readonly<
|
19 | 22 | Omit<HTMLAttributes<HTMLSpanElement>, "children"> & {
|
20 | 23 | contentType: keyof typeof featureStageBadgeTypes;
|
21 | 24 | labelText?: string;
|
22 |
| - size?: "sm" | "md" | "lg"; |
23 |
| - showTooltip?: boolean; |
| 25 | + size?: "sm" | "md"; |
24 | 26 | }
|
25 | 27 | >;
|
26 | 28 |
|
| 29 | +const badgeColorClasses = { |
| 30 | + early_access: |
| 31 | + "border-solid border-border-warning bg-surface-orange text-content-warning hover:bg-transparent", |
| 32 | + beta: "border-solid border-highlight-sky bg-surface-sky text-highlight-sky hover:bg-transparent", |
| 33 | +} as const; |
| 34 | + |
| 35 | +const badgeSizeClasses = { |
| 36 | + sm: "text-xs font-medium px-2 py-1", |
| 37 | + md: "text-base px-2 py-1", |
| 38 | +} as const; |
| 39 | + |
27 | 40 | export const FeatureStageBadge: FC<FeatureStageBadgeProps> = ({
|
28 | 41 | contentType,
|
29 | 42 | labelText = "",
|
30 | 43 | size = "md",
|
31 |
| - showTooltip = true, // This is a temporary until the deprecated popover is removed |
| 44 | + className, |
32 | 45 | ...delegatedProps
|
33 | 46 | }) => {
|
| 47 | + const colorClasses = badgeColorClasses[contentType]; |
| 48 | + const sizeClasses = badgeSizeClasses[size]; |
| 49 | + |
34 | 50 | return (
|
35 |
| - <Popover mode="hover"> |
36 |
| - <PopoverTrigger> |
37 |
| - {({ isOpen }) => ( |
38 |
| - <span |
39 |
| - css={[ |
40 |
| - styles.badge, |
41 |
| - size === "sm" && styles.badgeSmallText, |
42 |
| - size === "lg" && styles.badgeLargeText, |
43 |
| - isOpen && styles.badgeHover, |
44 |
| - ]} |
| 51 | + <TooltipProvider delayDuration={100}> |
| 52 | + <Tooltip> |
| 53 | + <TooltipTrigger asChild> |
| 54 | + <button |
| 55 | + className={cn( |
| 56 | + "block max-w-fit cursor-default flex-shrink-0 leading-none whitespace-nowrap border rounded-md transition-colors duration-200 ease-in-out bg-transparent", |
| 57 | + sizeClasses, |
| 58 | + colorClasses, |
| 59 | + className, |
| 60 | + )} |
45 | 61 | {...delegatedProps}
|
46 | 62 | >
|
47 |
| - <span style={visuallyHidden}> (This is a</span> |
| 63 | + <span className="sr-only"> (This is a</span> |
48 | 64 | <span className="first-letter:uppercase">
|
49 | 65 | {labelText && `${labelText} `}
|
50 | 66 | {featureStageBadgeTypes[contentType]}
|
51 | 67 | </span>
|
52 |
| - <span style={visuallyHidden}> feature)</span> |
53 |
| - </span> |
54 |
| - )} |
55 |
| - </PopoverTrigger> |
56 |
| - |
57 |
| - {showTooltip && ( |
58 |
| - <HelpTooltipContent |
59 |
| - anchorOrigin={{ vertical: "bottom", horizontal: "center" }} |
60 |
| - transformOrigin={{ vertical: "top", horizontal: "center" }} |
61 |
| - > |
62 |
| - <p css={styles.tooltipDescription}> |
| 68 | + <span className="sr-only"> feature)</span> |
| 69 | + </button> |
| 70 | + </TooltipTrigger> |
| 71 | + <TooltipContent align="start" className="max-w-xs text-sm"> |
| 72 | + <p className="m-0"> |
63 | 73 | This feature has not yet reached general availability (GA).
|
64 | 74 | </p>
|
65 | 75 |
|
66 | 76 | <Link
|
67 | 77 | href={docs("/install/releases/feature-stages")}
|
68 |
| - target="_blank" |
69 |
| - rel="noreferrer" |
70 |
| - css={styles.tooltipLink} |
| 78 | + className="font-semibold" |
71 | 79 | >
|
72 | 80 | Learn about feature stages
|
73 |
| - <span style={visuallyHidden}> (link opens in new tab)</span> |
| 81 | + <span className="sr-only"> (link opens in new tab)</span> |
74 | 82 | </Link>
|
75 |
| - </HelpTooltipContent> |
76 |
| - )} |
77 |
| - </Popover> |
| 83 | + </TooltipContent> |
| 84 | + </Tooltip> |
| 85 | + </TooltipProvider> |
78 | 86 | );
|
79 | 87 | };
|
80 |
| - |
81 |
| -const styles = { |
82 |
| - badge: (theme) => ({ |
83 |
| - // Base type is based on a span so that the element can be placed inside |
84 |
| - // more types of HTML elements without creating invalid markdown, but we |
85 |
| - // still want the default display behavior to be div-like |
86 |
| - display: "block", |
87 |
| - maxWidth: "fit-content", |
88 |
| - |
89 |
| - // Base style assumes that medium badges will be the default |
90 |
| - fontSize: "0.75rem", |
91 |
| - |
92 |
| - cursor: "default", |
93 |
| - flexShrink: 0, |
94 |
| - padding: "4px 8px", |
95 |
| - lineHeight: 1, |
96 |
| - whiteSpace: "nowrap", |
97 |
| - border: `1px solid ${theme.branding.featureStage.border}`, |
98 |
| - color: theme.branding.featureStage.text, |
99 |
| - backgroundColor: theme.branding.featureStage.background, |
100 |
| - borderRadius: "6px", |
101 |
| - transition: |
102 |
| - "color 0.2s ease-in-out, border-color 0.2s ease-in-out, background-color 0.2s ease-in-out", |
103 |
| - }), |
104 |
| - |
105 |
| - badgeHover: (theme) => ({ |
106 |
| - color: theme.branding.featureStage.hover.text, |
107 |
| - borderColor: theme.branding.featureStage.hover.border, |
108 |
| - backgroundColor: theme.branding.featureStage.hover.background, |
109 |
| - }), |
110 |
| - |
111 |
| - badgeLargeText: { |
112 |
| - fontSize: "1rem", |
113 |
| - }, |
114 |
| - |
115 |
| - badgeSmallText: { |
116 |
| - // Have to beef up font weight so that the letters still maintain the |
117 |
| - // same relative thickness as all our other main UI text |
118 |
| - fontWeight: 500, |
119 |
| - fontSize: "0.625rem", |
120 |
| - }, |
121 |
| - |
122 |
| - tooltipTitle: (theme) => ({ |
123 |
| - color: theme.palette.text.primary, |
124 |
| - fontWeight: 600, |
125 |
| - fontFamily: "inherit", |
126 |
| - fontSize: 18, |
127 |
| - margin: 0, |
128 |
| - lineHeight: 1, |
129 |
| - paddingBottom: "8px", |
130 |
| - }), |
131 |
| - |
132 |
| - tooltipDescription: { |
133 |
| - margin: 0, |
134 |
| - lineHeight: 1.4, |
135 |
| - paddingBottom: "8px", |
136 |
| - }, |
137 |
| - |
138 |
| - tooltipLink: { |
139 |
| - fontWeight: 600, |
140 |
| - lineHeight: 1.2, |
141 |
| - }, |
142 |
| -} as const satisfies Record<string, Interpolation<Theme>>; |
0 commit comments