summaryrefslogtreecommitdiffstats
path: root/browser/components/storybook/.storybook/addon-component-status
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/storybook/.storybook/addon-component-status')
-rw-r--r--browser/components/storybook/.storybook/addon-component-status/StatusIndicator.mjs114
-rw-r--r--browser/components/storybook/.storybook/addon-component-status/constants.mjs7
-rw-r--r--browser/components/storybook/.storybook/addon-component-status/index.js23
-rw-r--r--browser/components/storybook/.storybook/addon-component-status/preset/manager.mjs19
-rw-r--r--browser/components/storybook/.storybook/addon-component-status/preset/preview.mjs12
5 files changed, 175 insertions, 0 deletions
diff --git a/browser/components/storybook/.storybook/addon-component-status/StatusIndicator.mjs b/browser/components/storybook/.storybook/addon-component-status/StatusIndicator.mjs
new file mode 100644
index 0000000000..05d72146cb
--- /dev/null
+++ b/browser/components/storybook/.storybook/addon-component-status/StatusIndicator.mjs
@@ -0,0 +1,114 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// eslint-disable-next-line no-unused-vars
+import React from "react";
+import { useParameter } from "@storybook/api";
+import {
+ // eslint-disable-next-line no-unused-vars
+ Badge,
+ // eslint-disable-next-line no-unused-vars
+ WithTooltip,
+ // eslint-disable-next-line no-unused-vars
+ TooltipMessage,
+ // eslint-disable-next-line no-unused-vars
+ IconButton,
+} from "@storybook/components";
+import { TOOL_ID, STATUS_PARAM_KEY } from "./constants.mjs";
+
+const VALID_STATUS_MAP = {
+ stable: {
+ label: "Stable",
+ badgeType: "positive",
+ description:
+ "This component is widely used in Firefox, in both the chrome and in-content pages.",
+ },
+ "in-development": {
+ label: "In Development",
+ badgeType: "warning",
+ description:
+ "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.",
+ },
+ unstable: {
+ label: "Unstable",
+ badgeType: "negative",
+ description:
+ "This component is still in the early stages of development and may not be ready for general use in Firefox.",
+ },
+};
+
+/**
+ * Displays a badge with the components status in the Storybook toolbar.
+ *
+ * Statuses are set via story parameters.
+ * We support either passing `status: "statusType"` for using defaults or
+ * `status: {
+ type: "stable" | "in-development" | "unstable",
+ description: "Your description here"
+ links: [
+ {
+ title: "Link title",
+ href: "www.example.com",
+ },
+ ],
+ }`
+ * when we want to customize the description or add links.
+ */
+export const StatusIndicator = () => {
+ let componentStatus = useParameter(STATUS_PARAM_KEY, null);
+ let statusData = VALID_STATUS_MAP[componentStatus?.type ?? componentStatus];
+
+ if (!componentStatus || !statusData) {
+ return "";
+ }
+
+ // The tooltip message is added/removed from the DOM when visibility changes.
+ // We need to update the aira-describedby button relationship accordingly.
+ let onVisibilityChange = isVisible => {
+ let button = document.getElementById("statusButton");
+ if (isVisible) {
+ button.setAttribute("aria-describedby", "statusMessage");
+ } else {
+ button.removeAttribute("aria-describedby");
+ }
+ };
+
+ let description = componentStatus.description || statusData.description;
+ let links = componentStatus.links || [];
+
+ return (
+ <WithTooltip
+ key={TOOL_ID}
+ placement="top"
+ trigger="click"
+ style={{
+ display: "flex",
+ }}
+ onVisibilityChange={onVisibilityChange}
+ tooltip={() => (
+ <div id="statusMessage">
+ <TooltipMessage
+ title={statusData.label}
+ desc={description}
+ links={links}
+ />
+ </div>
+ )}
+ >
+ <IconButton
+ id="statusButton"
+ title={`Component status: ${statusData.label}`}
+ >
+ <Badge
+ status={statusData.badgeType}
+ style={{
+ boxShadow: "currentColor 0 0 0 1px inset",
+ }}
+ >
+ {statusData.label}
+ </Badge>
+ </IconButton>
+ </WithTooltip>
+ );
+};
diff --git a/browser/components/storybook/.storybook/addon-component-status/constants.mjs b/browser/components/storybook/.storybook/addon-component-status/constants.mjs
new file mode 100644
index 0000000000..84dc1983ac
--- /dev/null
+++ b/browser/components/storybook/.storybook/addon-component-status/constants.mjs
@@ -0,0 +1,7 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+export const ADDON_ID = "addon-component-status";
+export const TOOL_ID = `${ADDON_ID}/statusIndicator`;
+export const STATUS_PARAM_KEY = "status";
diff --git a/browser/components/storybook/.storybook/addon-component-status/index.js b/browser/components/storybook/.storybook/addon-component-status/index.js
new file mode 100644
index 0000000000..7f923e2de1
--- /dev/null
+++ b/browser/components/storybook/.storybook/addon-component-status/index.js
@@ -0,0 +1,23 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* eslint-env node */
+
+/**
+ * This file hooks our addon into Storybook. Having a root-level file like this
+ * is a Storybook requirement. It handles registering the addon without any
+ * additional user configuration.
+ */
+
+function config(entry = []) {
+ return [...entry, require.resolve("./preset/preview.mjs")];
+}
+
+function managerEntries(entry = []) {
+ return [...entry, require.resolve("./preset/manager.mjs")];
+}
+
+module.exports = {
+ managerEntries,
+ config,
+};
diff --git a/browser/components/storybook/.storybook/addon-component-status/preset/manager.mjs b/browser/components/storybook/.storybook/addon-component-status/preset/manager.mjs
new file mode 100644
index 0000000000..4aa611b156
--- /dev/null
+++ b/browser/components/storybook/.storybook/addon-component-status/preset/manager.mjs
@@ -0,0 +1,19 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/** This file handles registering the Storybook addon */
+
+// eslint-disable-next-line no-unused-vars
+import React from "react";
+import { addons, types } from "@storybook/addons";
+import { ADDON_ID, TOOL_ID } from "../constants.mjs";
+import { StatusIndicator } from "../StatusIndicator.mjs";
+
+addons.register(ADDON_ID, () => {
+ addons.add(TOOL_ID, {
+ type: types.TOOL,
+ title: "Pseudo Localization",
+ render: StatusIndicator,
+ });
+});
diff --git a/browser/components/storybook/.storybook/addon-component-status/preset/preview.mjs b/browser/components/storybook/.storybook/addon-component-status/preset/preview.mjs
new file mode 100644
index 0000000000..57f1378af6
--- /dev/null
+++ b/browser/components/storybook/.storybook/addon-component-status/preset/preview.mjs
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+export const globalTypes = {
+ componentStatus: {
+ name: "Component status",
+ description:
+ "Provides a visual indicator of the component's readiness status.",
+ defaultValue: "default",
+ },
+};