StatusIndicator.jsx (3352B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 // eslint-disable-next-line no-unused-vars 6 import React from "react"; 7 import { useParameter } from "@storybook/manager-api"; 8 import { 9 // eslint-disable-next-line no-unused-vars 10 Badge, 11 // eslint-disable-next-line no-unused-vars 12 WithTooltip, 13 // eslint-disable-next-line no-unused-vars 14 TooltipMessage, 15 // eslint-disable-next-line no-unused-vars 16 IconButton, 17 } from "@storybook/components"; 18 import { TOOL_ID, STATUS_PARAM_KEY } from "./constants.mjs"; 19 20 const VALID_STATUS_MAP = { 21 stable: { 22 label: "Stable", 23 badgeType: "positive", 24 description: 25 "This component is widely used in Firefox, in both the chrome and in-content pages.", 26 }, 27 "in-development": { 28 label: "In Development", 29 badgeType: "warning", 30 description: 31 "This component is in active development and starting to be used in Firefox. It may not yet be usable in both the chrome and in-content pages.", 32 }, 33 unstable: { 34 label: "Unstable", 35 badgeType: "negative", 36 description: 37 "This component is still in the early stages of development and may not be ready for general use in Firefox.", 38 }, 39 }; 40 41 /** 42 * Displays a badge with the components status in the Storybook toolbar. 43 * 44 * Statuses are set via story parameters. 45 * We support either passing `status: "statusType"` for using defaults or 46 * `status: { 47 type: "stable" | "in-development" | "unstable", 48 description: "Your description here" 49 links: [ 50 { 51 title: "Link title", 52 href: "www.example.com", 53 }, 54 ], 55 }` 56 * when we want to customize the description or add links. 57 */ 58 export const StatusIndicator = () => { 59 let componentStatus = useParameter(STATUS_PARAM_KEY, null); 60 let statusData = VALID_STATUS_MAP[componentStatus?.type ?? componentStatus]; 61 62 if (!componentStatus || !statusData) { 63 return ""; 64 } 65 66 // The tooltip message is added/removed from the DOM when visibility changes. 67 // We need to update the aira-describedby button relationship accordingly. 68 let onVisibilityChange = isVisible => { 69 let button = document.getElementById("statusButton"); 70 if (isVisible) { 71 button.setAttribute("aria-describedby", "statusMessage"); 72 } else { 73 button.removeAttribute("aria-describedby"); 74 } 75 }; 76 77 let description = componentStatus.description || statusData.description; 78 let links = componentStatus.links || []; 79 80 return ( 81 <WithTooltip 82 key={TOOL_ID} 83 placement="top" 84 trigger="click" 85 style={{ 86 display: "flex", 87 }} 88 onVisibleChange={onVisibilityChange} 89 tooltip={() => ( 90 <div id="statusMessage"> 91 <TooltipMessage 92 title={statusData.label} 93 desc={description} 94 links={links} 95 /> 96 </div> 97 )} 98 > 99 <IconButton 100 id="statusButton" 101 title={`Component status: ${statusData.label}`} 102 > 103 <Badge 104 status={statusData.badgeType} 105 style={{ 106 boxShadow: "currentColor 0 0 0 1px inset", 107 }} 108 > 109 {statusData.label} 110 </Badge> 111 </IconButton> 112 </WithTooltip> 113 ); 114 };