chore: remove storybook (#19659)

* remove storybook

* remove storybook trpc provider

* add user-event

* fix lockk file

---------

Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
This commit is contained in:
sean-brydon
2025-03-04 14:14:56 -07:00
committed by GitHub
co-authored by Bailey Pumfleet
parent fff521e171
commit d38b35b626
79 changed files with 8751 additions and 9265 deletions
-27
View File
@@ -1,27 +0,0 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
storybook-static/*
!storybook-static/favicon.ico
!storybook-static/sb-cover.jpg
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
-12
View File
@@ -1,12 +0,0 @@
import { create } from "@storybook/theming";
export default create({
base: "light",
colorPrimary: "#111827",
colorSecondary: "#111827",
appContentBg: "#F9FAFC",
brandTitle: "Cal.com UI",
brandUrl: "https://cal.com",
brandImage: "https://cal.com/logo.svg",
brandTarget: "_self",
});
-29
View File
@@ -1,29 +0,0 @@
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
const ns = ["common"];
const supportedLngs = ["en", "fr"];
const resources = ns.reduce((acc, n) => {
supportedLngs.forEach((lng) => {
if (!acc[lng]) acc[lng] = {};
acc[lng] = {
...acc[lng],
[n]: require(`../../web/public/static/locales/${lng}/${n}.json`),
};
});
return acc;
}, {});
i18n.use(initReactI18next).init({
debug: true,
fallbackLng: "en",
defaultNS: "common",
ns,
interpolation: {
escapeValue: false,
},
react: { useSuspense: true },
resources,
});
export default i18n;
-94
View File
@@ -1,94 +0,0 @@
import type { StorybookConfig } from "@storybook/nextjs";
import path, { dirname, join } from "path";
const config: StorybookConfig = {
stories: [
"../intro.stories.mdx",
"../../../packages/ui/components/**/*.stories.mdx", // legacy SB6 stories
"../../../packages/ui/components/**/*.stories.@(js|jsx|ts|tsx)",
"../../../packages/ui/components/**/*.docs.mdx",
"../../../packages/features/**/*.stories.@(js|jsx|ts|tsx)",
"../../../packages/features/**/*.docs.mdx",
],
addons: [
getAbsolutePath("@storybook/addon-links"),
getAbsolutePath("@storybook/addon-essentials"),
getAbsolutePath("@storybook/addon-interactions"),
getAbsolutePath("storybook-addon-rtl-direction"),
getAbsolutePath("storybook-react-i18next"),
],
framework: {
name: getAbsolutePath("@storybook/nextjs") as "@storybook/nextjs",
options: {
// builder: {
// fsCache: true,
// lazyCompilation: true,
// },
},
},
staticDirs: ["../public"],
webpackFinal: async (config, { configType }) => {
config.resolve = config.resolve || {};
config.resolve.fallback = {
fs: false,
assert: false,
buffer: false,
console: false,
constants: false,
crypto: false,
domain: false,
events: false,
http: false,
https: false,
os: false,
path: false,
punycode: false,
process: false,
querystring: false,
stream: false,
string_decoder: false,
sys: false,
timers: false,
tty: false,
url: false,
util: false,
vm: false,
zlib: false,
};
config.module = config.module || {};
config.module.rules = config.module.rules || [];
config.module.rules.push({
test: /\.css$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true, // Enable modules to help you using className
},
},
],
include: path.resolve(__dirname, "../src"),
});
return config;
},
typescript: { reactDocgen: "react-docgen" },
docs: {
autodocs: true,
},
};
export default config;
function getAbsolutePath(value) {
return dirname(require.resolve(join(value, "package.json")));
}
-7
View File
@@ -1,7 +0,0 @@
import { addons } from "@storybook/addons";
import yourTheme from "./YourTheme";
addons.setConfig({
theme: yourTheme,
});
@@ -1,9 +0,0 @@
<script>
window.global = window;
window.isEmbed = () => {
return location.search.includes("embed=");
};
</script>
<style>
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@500&display=swap");
</style>
-73
View File
@@ -1,73 +0,0 @@
// adds tooltip context to all stories
import { TooltipProvider } from "@radix-ui/react-tooltip";
import type { Preview } from "@storybook/react";
import React from "react";
import { I18nextProvider } from "react-i18next";
import type { EmbedThemeConfig } from "@calcom/embed-core/src/types";
// adds trpc context to all stories (esp. booker)
import { StorybookTrpcProvider } from "@calcom/ui";
import "../styles/globals.css";
import "../styles/storybook-styles.css";
import i18n from "./i18next";
const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
globals: {
locale: "en",
locales: {
en: "English",
fr: "Français",
},
},
i18n,
nextjs: {
appDirectory: true,
},
},
decorators: [
(Story) => (
<StorybookTrpcProvider>
<TooltipProvider>
<I18nextProvider i18n={i18n}>
<div style={{ margin: "2rem" }}>
<Story />
</div>
</I18nextProvider>
</TooltipProvider>
</StorybookTrpcProvider>
),
],
};
export default preview;
declare global {
interface Window {
getEmbedNamespace: () => string | null;
getEmbedTheme: () => EmbedThemeConfig | null;
}
}
window.getEmbedNamespace = () => {
const url = new URL(document.URL);
const namespace = url.searchParams.get("embed");
return namespace;
};
window.getEmbedTheme = () => {
return "auto";
};
@@ -1,23 +0,0 @@
import { ArgsTable } from "@storybook/addon-docs";
import type { SortType } from "@storybook/blocks";
import type { PropDescriptor } from "@storybook/preview-api";
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- ignore storybook addon types component as any so we have to do
type Component = any;
type BaseProps = {
include?: PropDescriptor;
exclude?: PropDescriptor;
sort?: SortType;
};
type OfProps = BaseProps & {
of: "." | "^" | Component;
};
export function CustomArgsTable({ of, sort }: OfProps) {
return (
<div className="custom-args-wrapper">
<ArgsTable of={of} sort={sort} />
</div>
);
}
-32
View File
@@ -1,32 +0,0 @@
import classNames from "@calcom/ui/classNames";
interface ExampleProps {
children: React.ReactNode;
title: string;
isFullWidth?: boolean;
}
export const Example = ({ children, title, isFullWidth = false }: ExampleProps) => {
return (
<div className={classNames("examples-item", isFullWidth && "w-full")}>
<span className={classNames("examples-item-title", isFullWidth && "mb-0 mt-2")}>{title}</span>
<div className="examples-item-content">{children}</div>
</div>
);
};
interface ExamplesProps {
children: React.ReactNode;
title: string;
footnote?: React.ReactNode;
dark?: boolean;
}
export const Examples = ({ children, title, footnote = null, dark }: ExamplesProps) => {
return (
<div className={classNames("examples", dark && "dark")}>
<h2 className="examples-title">{title}</h2>
<div className="examples-content">{children}</div>
{!!footnote && <div className="examples-footnote">{footnote}</div>}
</div>
);
};
-5
View File
@@ -1,5 +0,0 @@
export const Note = ({ children }: { children: React.ReactNode }) => (
<div className="story-note">
<div>{children}</div>
</div>
);
-21
View File
@@ -1,21 +0,0 @@
export const Title = ({
title,
suffix,
subtitle,
offset,
}: {
title: string;
suffix?: string;
subtitle?: string;
offset?: boolean;
}) => {
return (
<div className={`story-title ${offset && "offset"}`}>
<h1>
{title}
{suffix && <span>{suffix}</span>}
</h1>
{subtitle && <p>{subtitle}</p>}
</div>
);
};
@@ -1,82 +0,0 @@
import type { ReactElement, ReactNode } from "react";
import React from "react";
import classNames from "@calcom/ui/classNames";
export function VariantsTable({
children,
titles,
isDark,
columnMinWidth = 150,
}: {
children: ReactElement<RowProps> | ReactElement<RowProps>[];
titles: string[];
isDark?: boolean;
// Mainly useful on mobile, so components don't get squeesed
columnMinWidth?: number;
}) {
const columns = React.Children.toArray(children) as ReactElement<RowProps>[];
return (
<div
id="light-variant"
className={classNames(
isDark &&
"relative py-8 before:absolute before:left-0 before:top-0 before:block before:h-full before:w-screen before:bg-[#1C1C1C]"
)}>
<div className="z-1 relative mx-auto w-full max-w-[1200px] overflow-auto pr-8 pt-6">
<table>
<RowTitles titles={titles} />
{columns.map((column) => (
<tr className="p-2 pb-6 pr-6" key={column.props.variant}>
<th
className="p-2 pb-6 pr-6 text-left text-sm font-normal text-[#8F8F8F]"
key={column.props.variant}>
{column.props.variant}
</th>
{React.Children.count(column.props.children) &&
React.Children.map(column.props.children, (cell) => (
<td className="p-2 pb-6 pr-6" style={{ minWidth: `${columnMinWidth}px` }}>
{cell}
</td>
))}
</tr>
))}
</table>
</div>
{!isDark && (
<div id="dark-variant" data-mode="dark" className="dark">
<VariantsTable titles={titles} isDark columnMinWidth={columnMinWidth}>
{children}
</VariantsTable>
</div>
)}
</div>
);
}
interface RowProps {
variant: string;
children: ReactNode;
}
/**
* There are two reasons we have this "empty" wrapper component:
* 1. In order to have an isolate group per variant, which we iterate through in the table component.
* 2. To have a way to pass the variant.
*/
export function VariantRow({ children }: RowProps) {
return <>{children}</>;
}
export function RowTitles({ titles }: { titles: string[] }) {
return (
<tr>
<th className="p-2 pb-6 pr-6 text-left text-sm font-normal text-[#8F8F8F]" />
{titles.map((title) => (
<th className="p-2 pb-6 pr-6 text-left text-sm font-normal text-[#8F8F8F]" key={title}>
{title}
</th>
))}
</tr>
);
}
-5
View File
@@ -1,5 +0,0 @@
export * from "./Examples";
export * from "./Note";
export * from "./VariantsTable";
export * from "./Title";
export * from "./CustomArgsTable";
-18
View File
@@ -1,18 +0,0 @@
import { Meta } from "@storybook/addon-docs";
<Meta title="Introduction" />
<div className="flex flex-col items-center text-center">
<h1 style={{ marginBottom: "24px", marginTop: "36px" }}>Welcome to Cal.com UI</h1>
<p>
This is the beginning of our storybook improvements to match Figma as close as possible. Like our Figma
library, we will be adding more components as we go along.
</p>
<p>
Our <a href="https://www.figma.com/file/9MOufQNLtdkpnDucmNX10R/%E2%9D%96-Cal-DS" target="_blank">Figma</a>
library is available for anyone to view and use. If you have any questions or concerns, please reach out to
the design team.
</p>
</div>
<img src="/sb-cover.jpg" />
-42
View File
@@ -1,42 +0,0 @@
const withBundleAnalyzer = require("@next/bundle-analyzer");
const plugins = [];
plugins.push(withBundleAnalyzer({ enabled: process.env.ANALYZE === "true" }));
/** @type {import("next").NextConfig} */
const nextConfig = {
reactStrictMode: true,
images: {
domains: ["www.datocms-assets.com"],
formats: ["image/avif", "image/webp"],
},
typescript: {
ignoreBuildErrors: true,
},
transpilePackages: [
"@calcom/app-store",
"@calcom/dayjs",
"@calcom/emails",
"@calcom/trpc",
"@calcom/embed-core",
"@calcom/embed-react",
"@calcom/features",
"@calcom/lib",
"@calcom/prisma",
"@calcom/ui",
],
eslint: {
ignoreDuringBuilds: true,
},
webpack: (config, { isServer }) => {
if (!isServer) {
// don't resolve 'fs' module on the client to prevent this error on build --> Error: Can't resolve 'fs'
config.resolve.fallback = {
fs: false,
};
}
return config;
},
};
module.exports = () => plugins.reduce((acc, next) => next(acc), nextConfig);
-57
View File
@@ -1,57 +0,0 @@
{
"name": "@calcom/storybook",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "storybook dev -p 6006",
"build": "storybook build"
},
"dependencies": {
"@calcom/config": "*",
"@calcom/dayjs": "*",
"@calcom/ui": "*",
"@radix-ui/react-avatar": "^1.0.4",
"@radix-ui/react-collapsible": "^1.0.0",
"@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-id": "^1.0.0",
"@radix-ui/react-popover": "^1.0.2",
"@radix-ui/react-radio-group": "^1.0.0",
"@radix-ui/react-slider": "^1.0.0",
"@radix-ui/react-switch": "^1.0.0",
"@radix-ui/react-tooltip": "^1.0.0",
"@storybook/addon-docs": "^7.6.3",
"@storybook/blocks": "^7.6.3",
"@storybook/nextjs": "^7.6.3",
"@storybook/preview-api": "^7.6.3",
"next": "^13.5.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"storybook-addon-rtl-direction": "^0.0.19"
},
"devDependencies": {
"@babel/core": "^7.19.6",
"@storybook/addon-actions": "^7.6.3",
"@storybook/addon-designs": "^7.0.7",
"@storybook/addon-essentials": "^7.6.3",
"@storybook/addon-interactions": "^7.6.3",
"@storybook/addon-links": "^7.6.3",
"@storybook/nextjs": "^7.6.3",
"@storybook/react": "^7.6.3",
"@storybook/testing-library": "^0.2.2",
"@types/react": "18.0.26",
"@types/react-dom": "^18.0.9",
"@vitejs/plugin-react": "^2.2.0",
"autoprefixer": "^10.4.12",
"babel-loader": "^8.2.5",
"fs": "^0.0.1-security",
"postcss": "^8.4.18",
"postcss-pseudo-companion-classes": "^0.1.1",
"rollup-plugin-polyfill-node": "^0.10.2",
"storybook": "^7.6.3",
"storybook-react-i18next": "^2.0.9",
"tailwindcss": "^3.3.3",
"typescript": "^4.9.4",
"vite": "^4.1.2"
}
}
-23
View File
@@ -1,23 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
/**
* We use this postcss plugin to create custom css classes for
* any pseudo classes (eg hover, focus) mentioned below.
* This way you can eg show a hover state in Storybook by adding
* this classname .sb-pseudo--hover to the item.
*
* These styles will only be added in storybook, and will NOT
* end up in the final css bundle of apps using the components.
*/
[require.resolve("postcss-pseudo-companion-classes")]: {
prefix: "sb-pseudo--",
prefix: "sb-pseudo--",
// We have to keep a restrictTo list here, because otherwise
// this library will have issues processing tailwind's \: prefixed classes
// and start adding dots everywhere, breaking this functionality.
restrictTo: [":hover", ":focus"],
},
},
};
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 KiB

-10
View File
@@ -1,10 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "../../../packages/ui/styles/shared-globals.css";
:root {
--font-inter: "Inter var";
--font-cal: "Cal Sans";
}
-287
View File
@@ -1,287 +0,0 @@
@import url("../../../packages/features/calendars/weeklyview/styles/styles.css");
.sbdocs {
font-family: "Inter var" !important;
padding: 0 !important;
}
#docs-root {
overflow: hidden;
}
.sbdocs.sbdocs-h1 {
font-family: "Cal Sans", "sans-serif" !important;
font-weight: 600;
font-size: 36px;
margin: 0 0 82px 0;
}
.sbdocs.sbdocs-h2 {
font-size: 20px;
font-weight: 500;
border: none;
border-top: 2px solid rgba(0, 0, 0, 0.12);
padding-top: 12px !important;
padding-bottom: 12px !important;
margin: 82px 0 0 0;
}
.sbdocs.sbdocs-p {
max-width: 560px;
margin: 0 0 12px 0;
}
.sbdocs.sbdocs-content {
width: 1200px;
max-width: 100%;
}
/** Docs table **/
.custom-args-wrapper {
max-height: 400px;
overflow-y: scroll;
overflow-x: hidden;
margin-bottom: 1rem;
}
.docblock-argstable-body {
box-shadow: none !important;
font-size: 14px;
}
/* .docblock-argstable-head tr th, */
.docblock-argstable-body tr td {
/* padding-left: 0!important; */
padding: 20px !important;
}
/** Column titles **/
.docblock-argstable-body tr td > span,
.docblock-argstable-head tr th > span {
color: #525252 !important;
font-weight: 500 !important;
}
.docblock-argstable-body div p,
.docblock-argstable-body div span {
color: #8f8f8f !important;
}
/** Custom components **/
.story-title {
margin: 0 0 82px 0;
}
.story-title.offset {
margin-top: 100px;
}
.story-title h1 {
font-family: "Cal Sans", "sans-serif" !important;
font-weight: 600;
font-size: 36px;
}
.story-title h1 span {
color: #9ca3af;
font-family: "Inter var";
font-weight: normal;
display: inline-block;
margin-left: 8px;
}
.story-title p {
color: #111827;
font-size: 16px;
}
.examples {
background-color: #f9fafb;
padding: 20px;
display: flex;
flex-direction: column;
margin-bottom: 20px;
}
.examples-content {
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 30px 0;
}
.examples-title {
color: #8f8f8f;
font-size: 14px;
margin-bottom: 30px;
}
.examples-item-title {
font-size: 12px;
color: #8f8f8f;
margin-bottom: 12px;
display: block;
}
.examples-item {
margin: 0 20px;
}
.examples-footnote p,
.examples-footnote ul,
.examples-footnote li {
color: #8f8f8f;
font-size: 14px;
}
.examples-footnote ul {
padding-left: 8px;
}
.examples-footnote li {
margin: 0 !important;
}
.story-note {
background-color: #f9fafb;
font-size: 14px;
padding: 20px;
margin-bottom: 12px;
border-radius: 8px;
}
.story-note > div {
max-width: 600px;
}
/** SB Docs Preview **/
.sbdocs-preview {
width: 100vw;
left: calc((100vw - 1200px) / -2);
box-shadow: none !important;
margin: 0 !important;
border: none !important;
border-radius: none !important;
}
.docs-story > div:first-child {
padding: 0 !important;
margin: 0 !important;
}
.docs-story .innerZoomElementWrapper > div {
border: none !important;
}
.sb-main-padded {
padding: 0 !important;
}
@media screen and (max-width: 1200px) {
.sbdocs-preview {
left: -24px;
width: calc(100vw + 48px);
padding-left: 12px;
padding-right: 12px;
}
.sbdocs.sbdocs-content {
padding: 24px !important;
}
}
.docs-story {
padding: 24px !important;
}
@layer {
:root {
/* background */
--cal-bg-emphasis: hsla(220,13%,91%,1);
--cal-bg: hsla(0,0%,100%,1);
--cal-bg-subtle: hsla(220, 14%, 96%,1);
--cal-bg-muted: hsla(210,20%,98%,1);
--cal-bg-inverted: hsla(0,0%,6%,1);
/* background -> components*/
--cal-bg-info: hsla(218,83%,98%,1);
--cal-bg-success: hsla(134,76%,94%,1);
--cal-bg-attention: hsla(37, 86%, 92%, 1);
--cal-bg-error: hsla(3,66,93,1);
--cal-bg-dark-error: hsla(2, 55%, 30%, 1);
/* Borders */
--cal-border-emphasis: hsla(218, 11%, 65%, 1);
--cal-border: hsla(216, 12%, 84%, 1);
--cal-border-subtle: hsla(220, 13%, 91%, 1);
--cal-border-booker: #e5e7eb;
--cal-border-muted: hsla(220, 14%, 96%, 1);
--cal-border-error: hsla(4, 63%, 41%, 1);
/* Content/Text */
--cal-text-emphasis: hsla(217, 19%, 27%, 1);
--cal-text: hsla(217, 19%, 27%, 1);
--cal-text-subtle: hsla(220, 9%, 46%, 1);
--cal-text-muted: hsla(218, 11%, 65%, 1);
--cal-text-inverted: hsla(0, 0%, 100%, 1);
/* Content/Text -> components */
--cal-text-info: hsla(228, 56%, 33%, 1);
--cal-text-success: hsla(133, 34%, 24%, 1);
--cal-text-attention: hsla(16, 62%, 28%, 1);
--cal-text-error: hsla(0, 63%, 31%, 1);
/* Brand shinanigans
-> These will be computed for the users theme at runtime.
*/
--cal-brand: hsla(221, 39%, 11%, 1);
--cal-brand-emphasis: hsla(0, 0%, 6%, 1);
--cal-brand-text: hsla(0, 0%, 100%, 1);
}
.dark {
/* background */
--cal-bg-emphasis: hsla(0, 0%, 32%, 1);
--cal-bg: hsla(0, 0%, 10%, 1);
--cal-bg-subtle: hsla(0, 0%, 18%, 1);
--cal-bg-muted: hsla(0, 0%, 12%, 1);
--cal-bg-inverted: hsla(220, 14%, 96%, 1);
/* background -> components*/
--cal-bg-info: hsla(228, 56%, 33%, 1);
--cal-bg-success: hsla(133, 34%, 24%, 1);
--cal-bg-attention: hsla(16, 62%, 28%, 1);
--cal-bg-error: hsla(2, 55%, 30%, 1);
--cal-bg-dark-error: hsla(2, 55%, 30%, 1);
/* Borders */
--cal-border-emphasis: hsla(0, 0%, 46%, 1);
--cal-border: hsla(0, 0%, 34%, 1);
--cal-border-subtle: hsla(0, 0%, 22%, 1);
--cal-border-booker: hsla(0, 0%, 22%, 1);
--cal-border-muted: hsla(0, 0%, 18%, 1);
--cal-border-error: hsla(4, 63%, 41%, 1);
/* Content/Text */
--cal-text-emphasis: hsla(240, 20%, 99%, 1);
--cal-text: hsla(0, 0%, 84%, 1);
--cal-text-subtle: hsla(0, 0%, 65%, 1);
--cal-text-muted: hsla(0, 0%, 34%, 1);
--cal-text-inverted: hsla(0, 0%, 10%, 1);
/* Content/Text -> components */
--cal-text-info: hsla(218, 83%, 93%, 1);
--cal-text-success: hsla(134, 76%, 94%, 1);
--cal-text-attention: hsla(37, 86%, 92%, 1);
--cal-text-error: hsla(3, 66%, 93%, 1);
/* Brand shenanigans
-> These will be computed for the users theme at runtime.
*/
--cal-brand: hsla(0, 0%, 100%, 1);
--cal-brand-emphasis: hsla(218, 11%, 65%, 1);
--cal-brand-text: hsla(0, 0%, 0%,1);
}
}
-7
View File
@@ -1,7 +0,0 @@
const base = require("@calcom/config/tailwind-preset");
/** @type {import('tailwindcss').Config} */
module.exports = {
...base,
darkMode: ["class", '[data-mode="dark"]'],
content: [...base.content, "../../packages/ui/**/*.{js,ts,jsx,tsx,mdx}", "./stories/**/*.{js,ts,tsx,jsx}"],
};
-9
View File
@@ -1,9 +0,0 @@
{
"extends": "@calcom/tsconfig/nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["**/node_modules/**"],
"compilerOptions": {
"noImplicitAny": false,
"baseUrl": "."
}
}
-8
View File
@@ -1,8 +0,0 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
}
}
@@ -1,24 +0,0 @@
import { Canvas, Meta } from "@storybook/blocks";
import { Title, CustomArgsTable } from "@calcom/storybook/components";
import { VerifyCodeDialog } from "./VerifyCodeDialog";
import * as VerifyCodeDialogStories from "./VerifyCodeDialog.stories";
<Meta of={VerifyCodeDialogStories} />
<Title title="VerifyCodeDialog" suffix="Brief" subtitle="Version 1.0 — Last Update: 11 Sep 2023" />
## Definition
The `VerifyCodeDialog` component allows users to enter a verification code sent to their email. The component provides feedback in case of an error and can handle different verification processes depending on whether the user session is required.
## Structure
This component contains an input form to capture a 6-digit verification code, error handling UI, and action buttons.
<CustomArgsTable of={VerifyCodeDialog} />
{/* ## VerifyCodeDialog Story
<Canvas of={VerifyCodeDialogStories.Default} /> */}
@@ -1,48 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react";
import type { ComponentProps } from "react";
import { StorybookTrpcProvider } from "@calcom/ui";
import { VerifyCodeDialog } from "./VerifyCodeDialog";
type StoryArgs = ComponentProps<typeof VerifyCodeDialog>;
const meta: Meta<StoryArgs> = {
component: VerifyCodeDialog,
title: "Features/VerifyCodeDialog",
argTypes: {
isOpenDialog: { control: "boolean", description: "Indicates whether the dialog is open or not." },
setIsOpenDialog: { action: "setIsOpenDialog", description: "Function to set the dialog state." },
email: { control: "text", description: "Email to which the verification code was sent." },
onSuccess: { action: "onSuccess", description: "Callback function when verification succeeds." },
// onError: { action: "onError", description: "Callback function when verification fails." },
isUserSessionRequiredToVerify: {
control: "boolean",
description: "Indicates if user session is required for verification.",
},
},
decorators: [
(Story) => (
<StorybookTrpcProvider>
<Story />
</StorybookTrpcProvider>
),
],
render: (args) => <VerifyCodeDialog {...args} />,
};
export default meta;
type Story = StoryObj<StoryArgs>;
export const Default: Story = {
name: "Dialog",
args: {
isOpenDialog: true,
email: "example@email.com",
// onError: (err) => {
// if (err.message === "invalid_code") {
// alert("Code provided is invalid");
// }
// },
},
};
@@ -1,13 +0,0 @@
import { Canvas, Meta } from "@storybook/blocks";
import { Title } from "@calcom/storybook/components";
import * as EventMetaStories from "./EventMeta.stories";
<Meta of={EventMetaStories} />
<Title title="Event Meta" suffix="Brief" subtitle="Version 2.0 — Last Update: 12 Dec 2022" />
<Canvas of={EventMetaStories.ExampleStory} />
<Canvas of={EventMetaStories.AllVariants} />
@@ -1,67 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react";
import type { ComponentProps } from "react";
import { Examples, Example, VariantsTable, VariantRow } from "@calcom/storybook/components";
import { EventDetails } from "./Details";
import { EventMembers } from "./Members";
import { EventTitle } from "./Title";
import { mockEvent } from "./event.mock";
type StoryArgs = ComponentProps<typeof EventDetails>;
const meta: Meta<StoryArgs> = {
component: EventDetails,
parameters: {
nextjs: {
appDirectory: true,
},
},
title: "Features/Events/Meta",
};
export default meta;
type Story = StoryObj<StoryArgs>;
export const ExampleStory: Story = {
name: "Examples",
render: () => (
<Examples title="Combined event meta block">
<div style={{ maxWidth: 300 }}>
<Example title="Event Title">
<EventTitle>{mockEvent.title}</EventTitle>
</Example>
<Example title="Event Details">
<EventDetails event={mockEvent} />
</Example>
</div>
</Examples>
),
};
export const AllVariants: Story = {
name: "All variants",
render: () => (
<VariantsTable titles={["Event Meta Components"]} columnMinWidth={150}>
<VariantRow variant="">
<div style={{ maxWidth: 300 }}>
<EventMembers
users={mockEvent.users}
schedulingType="COLLECTIVE"
entity={{
considerUnpublished: false,
fromRedirectOfNonOrgLink: true,
teamSlug: null,
name: "Example",
orgSlug: null,
}}
// TODO remove type assertion
profile={{ bookerLayouts: null }}
/>
<EventTitle>Quick catch-up</EventTitle>
<EventDetails event={mockEvent} />
</div>
</VariantRow>
</VariantsTable>
),
};
@@ -1,78 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
VariantsTable,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import dayjs from "@calcom/dayjs";
import DatePicker from "./DatePicker";
<Meta title="UI/DatePicker" component={DatePicker} />
<Title title="DatePicker" suffix="Brief" subtitle="Version 1.0 — Last Update: 21 Aug 2023" />
## Definition
DatePicker is a clickable element that allows the user to select a specific date from the available list in the component.
## Structure
DatePicker component offers a complete and customizable element for the user to select a specific date in the calendar.
<CustomArgsTable of={DatePicker} />
<Examples title="DatePicker">
<Example title="Default">
<DatePicker />
</Example>
</Examples>
<Title offset title="DatePicker" suffix="Variants" />
<Canvas>
<Story
name="DatePicker"
args={{
weekStart: 0,
excludedDates: ["2023-08-20", "2023-08-21"],
minDate: dayjs("2023-07-23").utc(),
maxDate: dayjs("2023-08-30").utc(),
selected: dayjs("2023-08-30").utc(),
isPending: false,
onChange: (newDate) => console.log(newDate),
onMonthChange: (newMonth) => console.log(newMonth),
}}
argTypes={{
weekStart: {
control: {
type: "inline-radio",
options: [0, 1, 2, 3, 4, 5, 6],
},
},
selected: {
control: "date"
}
}}>
{({ weekStart, excludedDates, onChange, onMonthChange, minDate, maxDate, selected, isPending }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow variant="Default">
<DatePicker
weekStart={weekStart}
excludedDates={excludedDates}
minDate={dayjs(minDate).utc()}
maxDate={dayjs(maxDate).utc()}
onChange={onChange}
onMonthChange={onMonthChange}
selected={dayjs(selected)}
isPending={isPending}
/>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,84 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { TooltipProvider } from "@radix-ui/react-tooltip";
import {
Title,
CustomArgsTable,
} from "@calcom/storybook/components";
import { events, blockingDates } from "../_storybookData";
import "../styles/styles.css";
import { Calendar } from "./Calendar";
<Meta title="UI/Calendar" component="calendar" />
<Title title="Calendar" suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Props
The Args Table below shows you a breakdown of what props can be passed into the Calendar component. All props should have a description to make it self explanatory to see what is going on.
<CustomArgsTable of="calendar" />
## Example
There will be a few examples of how to use the Calendar component to show different usecases.
export const Template = (args) => <TooltipProvider><Calendar {...args} /></TooltipProvider>;
<Canvas>
<Story
name="Customising Start Hour and EndHour"
argTypes={{
startHour: {
control: { type: "number", min: 0, max: 23, step: 1 },
},
endHour: {
control: { type: "number", min: 0, max: 23, step: 1 },
},
}}
args={{
sortEvents: true,
startHour: 8,
endHour: 20,
events: events,
hoverEventDuration: 0,
blockingDates: blockingDates,
}}>
{Template.bind({})}
</Story>
</Canvas>
<Canvas>
<Story
name="Onclick Handlers"
args={{
startHour: 8,
endHour: 17,
hoverEventDuration: 30,
}}
argTypes={{
startHour: {
control: { type: "number", min: 0, max: 23, step: 1 },
},
endHour: {
control: { type: "number", min: 0, max: 23, step: 1 },
},
hoverEventDuration: {
control: { type: "number", min: 0, max: 60, step: 1 },
},
}}>
{({ ...args }) => (
<TooltipProvider>
<Calendar
{...args}
events={events}
onEventClick={(e) => alert(e.title)}
onEmptyCellClick={(date) => alert(date.toString())}
sortEvents
/>
</TooltipProvider>
)}
</Story>
</Canvas>
@@ -1,16 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react";
import { BookerWebWrapper as Booker } from "./BookerWebWrapper";
const meta: Meta<typeof Booker> = {
component: Booker,
title: "Atoms/Booker",
};
export default meta;
type Story = StoryObj<typeof Booker>;
export const Default: Story = {
name: "Booker",
render: () => <Booker username="pro" eventSlug="" entity={{}} />,
};
@@ -1,43 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import { Examples, Example, Note, Title, CustomArgsTable } from "@calcom/storybook/components";
import TokenHandler from "./TokenHandler";
<Meta title="UI/TokenHandler" component={TokenHandler} />
<Title title="TokenHandler" subtitle="Version 0.1" />
## Structure
<TokenHandler
digits={[
{
value: "1",
onChange: (e) => {},
},
{
value: "2",
onChange: (e) => {},
},
{
value: "3",
onChange: (e) => {},
},
{
value: "4",
onChange: (e) => {},
},
{
value: "5",
onChange: (e) => {},
},
{
value: "6",
onChange: (e) => {},
},
]}
digitClassName="digit-input"
/>
#all the numbers should be visible while the first one is focused
@@ -1,94 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Alert } from "./Alert";
<Meta title="UI/Alert" component={Alert} />
<Title title="Alert" suffix="Brief" subtitle="Version 2.0 — Last Update: 04 jan 2023" />
## Definition
Alerts provide time-based feedback to the user after taking an action.
## Structure
Each alert has a state to represent neutral, positive or negative responses.
<CustomArgsTable of={Alert} />
<Examples title="Alert style">
<Example title="Error">
<Alert
severity="error"
title="Summarise what happened"
message="Describe what can be done about it here."
/>
</Example>
<Example title="Warning">
<Alert
severity="warning"
title="Summarise what happened"
message="Describe what can be done about it here."
/>
</Example>
<Example title="With actions">
<Alert
severity="warning"
title="Summarise what happened"
message="Describe what can be done about it here."
actions={
<>
<button>Cancel me</button>
</>
}
/>
</Example>
</Examples>
<Title offset title="Alert" suffix="Variants" />
<Canvas>
<Story
name="Alert"
args={{
severity: "success",
title: "Summarise what happened",
message: "Describe what can be done about it here.",
}}
argTypes={{
severity: {
control: {
type: "inline-radio",
options: ["success", "warning", "error", "neutral", "info"],
},
},
title: {
control: {
type: "text",
},
},
message: {
control: {
type: "text",
},
},
}}>
{({ severity, title, message }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow variant={severity}>
<Alert severity={severity} title={title} message={message} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,30 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { AppStoreCategories as Categories } from "./Categories";
import { _SBAppCategoryList } from "./_storybookData";
<Meta title="UI/apps/Categories" component={Categories} />
<Title title="Categories" suffix="Brief" subtitle="Version 2.0 — Last Update: 03 Jan 2023" />
## Definition
Categories that is used in our appstore.
<CustomArgsTable of={Categories} />
## Examples
We don't currently mock translations in storybook so the stories will display placeholder text.
<Categories categories={_SBAppCategoryList} />
@@ -1,167 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Avatar } from "./Avatar";
import { AvatarGroup } from "./AvatarGroup";
<Meta title="UI/Avatar" component={Avatar} />
<Title title="Avatar" suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Definition
An avatar group signals that there is more than 1 person associated with an item
## Structure
Avatar group can be composed differently based on the number of user profile.
<CustomArgsTable of={Avatar} />
<Examples title="Avatar style">
<Example title="Small">
<Avatar size="sm" alt="Avatar Story" />
</Example>
<Example title="Large">
<Avatar size="lg" alt="Avatar Story" />
</Example>
</Examples>
<ArgsTable of={Avatar} />
### Avatar Group
<ArgsTable of={AvatarGroup} />
<Examples title="Avatar Group ">
<Example title="Small">
<AvatarGroup
size="sm"
items={[
{
image: "https://cal.com/stakeholder/peer.jpg",
alt: "Peer",
title: "Peer Richelsen",
},
{
image: "https://cal.com/stakeholder/bailey.jpg",
alt: "Bailey",
title: "Bailey Pumfleet",
},
{
image: "https://cal.com/stakeholder/alex-van-andel.jpg",
alt: "Alex",
title: "Alex Van Andel",
},
{
image: "https://cal.com/stakeholder/ciaran.jpg",
alt: "Ciarán",
title: "Ciarán Hanrahan",
},
{
image: "https://cal.com/stakeholder/peer.jpg",
alt: "Peer",
title: "Peer Richelsen",
},
{
image: "https://cal.com/stakeholder/bailey.jpg",
alt: "Bailey",
title: "Bailey Pumfleet",
},
{
image: "https://cal.com/stakeholder/alex-van-andel.jpg",
alt: "Alex",
title: "Alex Van Andel",
},
{
image: "https://cal.com/stakeholder/ciaran.jpg",
alt: "Ciarán",
title: "Ciarán Hanrahan",
},
]}
/>
</Example>
<Example title="large">
<AvatarGroup
size="lg"
items={[
{
image: "https://cal.com/stakeholder/peer.jpg",
alt: "Peer",
title: "Peer Richelsen",
},
{
image: "https://cal.com/stakeholder/bailey.jpg",
alt: "Bailey",
title: "Bailey Pumfleet",
},
{
image: "https://cal.com/stakeholder/alex-van-andel.jpg",
alt: "Alex",
title: "Alex Van Andel",
},
{
image: "https://cal.com/stakeholder/ciaran.jpg",
alt: "Ciarán",
title: "Ciarán Hanrahan",
},
{
image: "https://cal.com/stakeholder/peer.jpg",
alt: "Peer",
title: "Peer Richelsen",
},
{
image: "https://cal.com/stakeholder/bailey.jpg",
alt: "Bailey",
title: "Bailey Pumfleet",
},
{
image: "https://cal.com/stakeholder/alex-van-andel.jpg",
alt: "Alex",
title: "Alex Van Andel",
},
{
image: "https://cal.com/stakeholder/ciaran.jpg",
alt: "Ciarán",
title: "Ciarán Hanrahan",
},
]}
/>
</Example>
</Examples>
<Title offset title="Avatar" suffix="Variants" />
<Canvas>
<Story
name="Avatar"
args={{
size: "sm",
alt: "Avatar Story",
}}
argTypes={{
size: {
control: {
type: "inline-radio",
options: ["sm", "lg"],
},
},
alt: { control: "text" },
}}>
{({ size, alt }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow variant={size}>
<Avatar size={size} alt={alt} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,99 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Plus } from "../icon";
import { Badge } from "./Badge";
<Meta title="UI/Badge" component={Badge} />
<Title title="Badge" suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Definition
Badges are small status descriptors for UI elements. A badge consists of a small circle, typically containing a number or other short set of characters, that appears in proximity to another object. We provide three different types of badges such as status, alert, and brand badge.
Status badge communicate status information. It is generally used within a container such as accordion and tables to label status for easy scanning.
## Structure
<CustomArgsTable of={Badge} />
<Examples title="Badge style">
<Example title="Gray">
<Badge variant="gray">Badge text</Badge>
</Example>
<Example title="Green/Success">
<Badge variant="success">Badge text</Badge>
</Example>
<Example title="Orange/Default">
<Badge variant="default">Badge text</Badge>
</Example>
<Example title="Red/Error">
<Badge variant="red">Badge text</Badge>
</Example>
</Examples>
<Examples title="Variants">
<Example title="Default">
<Badge>Button text</Badge>
</Example>
<Example title="With Dot">
<Badge withDot>Button Text</Badge>
</Example>
<Example title="With Icon">
<Badge startIcon="plus">Button Text</Badge>
</Example>
</Examples>
## Alert Badges
## Usage
Alert badge is used in conjunction with an item, profile or label to indicate numeric value and messages associated with them.
<Title offset title="Badge" suffix="Variants" />
<Canvas>
<Story
name="All Variants"
args={{
severity: "default",
label: "Badge text",
}}
argTypes={{
severity: {
control: {
type: "inline-radio",
options: ["default", "success", "gray", "error"],
},
},
label: {
control: {
type: "text",
},
},
}}>
{({ severity, label }) => (
<VariantsTable titles={["Default", "With Dot", "With Icon"]} columnMinWidth={150}>
<VariantRow variant={severity}>
<Badge variant={severity}>{label}</Badge>
<Badge variant={severity} withDot>
{label}
</Badge>
<Badge variant={severity} startIcon="plus">
{label}
</Badge>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,26 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import { Examples, Example, Note, Title, CustomArgsTable } from "@calcom/storybook/components";
import { Breadcrumb, BreadcrumbItem } from "./Breadcrumb";
<Meta title="UI/Breadcrumbs" component={Breadcrumb} />
<Title title="Breadcrumbs" suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Structure
<CustomArgsTable of={Breadcrumb} />
<Examples title="Breadcrumb style">
<Example title="Primary">
<Breadcrumb>
<BreadcrumbItem href="/">Home</BreadcrumbItem>
<BreadcrumbItem href="/">Test</BreadcrumbItem>
</Breadcrumb>
</Example>
</Examples>
## Usage
When hovering over the button, there should be a tooltip to explain the context of the button, so the user can understand the result of action.
@@ -1,244 +0,0 @@
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
VariantsTable,
VariantColumn,
RowTitles,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Plus, X } from "../icon";
import { Button } from "./Button";
<Meta title="UI/Button" component={Button} />
<Title title="Buttons" suffix="Brief" subtitle="Version 2.1 — Last Update: 24 Aug 2023" />
## Definition
Button are clickable elements that initiates user actions. Labels in the button guide users to what action will occur when the user interacts with it.
## Structure
<CustomArgsTable of={Button} />
<Examples
title="Button style"
footnote={
<ul>
<li>Primary: Signals most important actions at any given point in the application.</li>
<li>Secondary: Gives visual weight to actions that are important</li>
<li>Minimal: Used for actions that we want to give very little significane to</li>
</ul>
}>
<Example title="Primary">
<Button className="sb-fake-pseudo--focus">Button text</Button>
</Example>
<Example title="Secondary">
<Button color="secondary">Button text</Button>
</Example>
<Example title="Minimal">
<Button color="minimal">Button text</Button>
</Example>
</Examples>
<Examples title="State">
<Example title="Default">
<Button>Button text</Button>
</Example>
<Example title="Hover">
<Button className="sb-pseudo--hover">Button text</Button>
</Example>
<Example title="Focus">
<Button className="sb-pseudo--focus">Button text</Button>
</Example>
<Example title="Disabled">
<Button disabled>Button text</Button>
</Example>
<Example title="Loading">
<Button loading>Button text</Button>
</Example>
</Examples>
<Examples title="Icons">
<Example title="Default">
<Button>Button text</Button>
</Example>
<Example title="Icon left">
<Button StartIcon="plus">Button text</Button>
</Example>
<Example title="Icon right">
<Button EndIcon="plus">Button text</Button>
</Example>
</Examples>
<Examples title="Icons">
<Example title="Icon Normal">
<Button StartIcon="x" variant="icon" size="base" color="minimal"></Button>
</Example>
<Example title="Icon Small">
<Button StartIcon="x" variant="icon" size="sm" color="minimal"></Button>
</Example>
<Example title="Icon Loading">
<Button StartIcon="x" variant="icon" size="sm" color="minimal" loading></Button>
</Example>
</Examples>
## Anatomy
Button are clickable elements that initiates user actions. Labels in the button guide users to what action will occur when the user interacts with it.
## Usage
<Note>In general, there should be only one Primary button in any application context</Note>
<Note>
Aim to use maximum 2 words for the button label. Button size can be flexible based on the visual hierarchy
and devices.{" "}
</Note>
<Note>Hover state variant for Mobile button is an option for assistive device.</Note>
<Title offset title="Buttons" suffix="Variants" />
<Canvas>
<Story name="All variants">
<VariantsTable titles={["Primary", "Secondary", "Minimal", "Destructive", "Icon"]} columnMinWidth={150}>
<VariantRow variant="Default">
<Button>Button text</Button>
<Button color="secondary">Button text</Button>
<Button color="minimal">Button text</Button>
<Button color="destructive">Button text</Button>
<Button color="destructive" variant="icon" StartIcon="x"></Button>
</VariantRow>
<VariantRow variant="Hover">
<Button className="sb-pseudo--hover">Button text</Button>
<Button className="sb-pseudo--hover" color="secondary">
Button text
</Button>
<Button className="sb-pseudo--hover" color="minimal">
Button text
</Button>
<Button className="sb-pseudo--hover" color="destructive">
Button text
</Button>
<Button className="sb-pseudo--hover" color="destructive" variant="icon" StartIcon="x"></Button>
</VariantRow>
<VariantRow variant="Focus">
<Button className="sb-pseudo--focus">Button text</Button>
<Button className="sb-pseudo--focus" color="secondary">
Button text
</Button>
<Button className="sb-pseudo--focus" color="minimal">
Button text
</Button>
<Button className="sb-pseudo--focus" color="destructive">
Button text
</Button>
<Button className="sb-pseudo--focus" color="destructive" variant="icon" StartIcon="x"></Button>
</VariantRow>
<VariantRow variant="Loading">
<Button loading>Button text</Button>
<Button loading color="secondary">
Button text
</Button>
<Button loading color="minimal">
Button text
</Button>
<Button loading color="destructive">
Button text
</Button>
<Button loading color="destructive" variant="icon" StartIcon="x"></Button>
</VariantRow>
<VariantRow variant="Disabled">
<Button disabled>Button text</Button>
<Button disabled color="secondary">
Button text
</Button>
<Button disabled color="minimal">
Button text
</Button>
<Button disabled color="destructive">
Button text
</Button>
<Button disabled color="minimal" variant="icon" StartIcon="x"></Button>
</VariantRow>
</VariantsTable>
</Story>
<Story
name="Button Playground"
play={({ canvasElement }) => {
const darkVariantContainer = canvasElement.querySelector('[data-mode="dark"]');
const buttonElement = darkVariantContainer.querySelector("button");
buttonElement?.addEventListener("mouseover", () => {
setTimeout(() => {
document.querySelector('[data-testid="tooltip"]').classList.add("dark");
}, 55);
});
}}
args={{
color: "primary",
size: "base",
loading: false,
disabled: false,
children: "Button text",
className: "",
tooltip: "tooltip",
}}
argTypes={{
color: {
control: {
type: "inline-radio",
options: ["primary", "secondary", "minimal", "destructive"],
},
},
size: {
control: {
type: "inline-radio",
options: ["base", "sm"],
},
},
loading: {
control: {
type: "boolean",
},
},
disabled: {
control: {
type: "boolean",
},
},
children: {
control: {
type: "text",
},
},
className: {
control: {
type: "inline-radio",
options: ["", "sb-pseudo--hover", "sb-pseudo--focus"],
},
},
tooltip: {
control: {
type: "text",
},
},
}}>
{({ children, ...args }) => (
<VariantsTable titles={["Light & Dark Modes"]} columnMinWidth={150}>
<VariantRow variant="Button">
<TooltipProvider>
<Button variant="default" {...args}>
{children}
</Button>
</TooltipProvider>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,124 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Icon } from "@calcom/ui/icon";
import { Button } from "@calcom/ui/button";
import { ButtonGroup } from "@calcom/ui/buttonGroup";
<Meta title="UI/Button Group" component={ButtonGroup} />
<Title title="Button Group" suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Definition
Button group enables multiple buttons to be combined into a single unit. It offers users access to frequently performed, related actions.
## Structure
<CustomArgsTable of={ButtonGroup} />
<Examples
title="Breadcrumb style"
footNote={
<ul>
<li>
Separated: In general, separated button group style can be included in container such as card, modal,
and page.
</li>
<li>Combined: Combined button group can be used standalone e.g. mini toggles for calendars</li>
</ul>
}>
<Example title="Default">
<ButtonGroup>
<Button StartIcon="trash" variant="icon" color="secondary" />
<Button StartIcon="navigation" variant="icon" color="secondary" />
<Button StartIcon="clipboard" variant="icon" color="secondary" />
</ButtonGroup>
</Example>
<Example title="Combined">
<ButtonGroup combined>
<Button StartIcon="trash" variant="icon" color="secondary" />
<Button StartIcon="navigation" variant="icon" color="secondary" />
<Button StartIcon="clipboard" variant="icon" color="secondary" />
</ButtonGroup>
</Example>
</Examples>
<Canvas>
<Story name="All Variants">
<VariantsTable titles={["Default", "Secondary", "Minimal"]} columnMinWidth={150}>
<VariantRow variant="Default">
<ButtonGroup>
<Button StartIcon="trash" variant="icon" />
<Button StartIcon="navigation" variant="icon" />
<Button StartIcon="clipboard" variant="icon" />
</ButtonGroup>
<ButtonGroup>
<Button StartIcon="trash" variant="icon" color="secondary" />
<Button StartIcon="navigation" variant="icon" color="secondary" />
<Button StartIcon="clipboard" variant="icon" color="secondary" />
</ButtonGroup>
<ButtonGroup>
<Button StartIcon="trash" variant="icon" color="minimal" />
<Button StartIcon="navigation" variant="icon" color="minimal" />
<Button StartIcon="clipboard" variant="icon" color="minimal" />
</ButtonGroup>
</VariantRow>
<VariantRow variant="Combined">
<ButtonGroup combined>
<Button StartIcon="trash" variant="icon" />
<Button StartIcon="navigation" variant="icon" />
<Button StartIcon="clipboard" variant="icon" />
</ButtonGroup>
<ButtonGroup combined>
<Button StartIcon="trash" variant="icon" color="secondary" />
<Button StartIcon="navigation" variant="icon" color="secondary" />
<Button StartIcon="clipboard" variant="icon" color="secondary" />
</ButtonGroup>
</VariantRow>
</VariantsTable>
</Story>
</Canvas>
<Canvas>
<Story
name="ButtonGroup Playground"
args={{
color: "secondary",
combined: false,
}}
argTypes={{
color: {
control: {
type: "select",
options: ["primary", "secondary", "minimal"],
},
},
combined: {
control: {
type: "boolean",
},
},
}}>
{({ color, combined }) => (
<VariantsTable titles={[`${color}`]} columnMinWidth={150}>
<VariantRow variant="">
<ButtonGroup combined={combined}>
<Button StartIcon="trash" variant="icon" color={color} />
<Button StartIcon="navigation" variant="icon" color={color} />
<Button StartIcon="clipboard" variant="icon" color={color} />
</ButtonGroup>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,69 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import Card from "./Card";
<Meta title="UI/Card" component={Card} />
<Title title="Card" suffix="Brief" subtitle="Version 2.0 — Last Update: 06 Jan 2023" />
## Definition
All Cards used in Cal.com
<CustomArgsTable of={Card} />
export const tip = {
id: 1,
thumbnailUrl: "https://img.youtube.com/vi/60HJt8DOVNo/0.jpg",
mediaLink: "https://go.cal.com/dynamic-video",
title: "Dynamic booking links",
description: "Booking link that allows people to quickly schedule meetings.",
href: "https://cal.com/blog/cal-v-1-9",
};
<Canvas>
<Story
name="Card"
args={{
thumbnailUrl: tip.thumbnailUrl,
mediaLink: tip.mediaLink,
title: tip.title,
description: tip.description,
learnMoreHref: tip.href,
learnMoreText: "learn more",
}}
argTypes={{
thumbnailUrl: { control: { type: "text" } },
mediaLink: { control: { type: "text" } },
title: { control: { type: "text" } },
description: { control: { type: "text" } },
learnMoreHref: { control: { type: "text" } },
learnMoreText: { control: { type: "text" } },
}}>
{({ thumbnailUrl, mediaLink, title, description, learnMoreText }) => (
<VariantsTable titles={[""]} columnMinWidth={150}>
<VariantRow variant="Sidebar Card">
<Card
variant="SidebarCard"
thumbnailUrl={thumbnailUrl}
mediaLink={mediaLink}
title={title}
description={description}
learnMore={{ href: tip.href, text: learnMoreText }}
actionButton={{ onClick: () => console.log("Clicked") }}
/>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,31 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import Credits from "./Credits";
<Meta title="UI/Credits" component={Credits} />
<Title title="Credits" suffix="Brief" subtitle="Version 2.0 — Last Update: 05 jan 2023" />
## Definition
Shows the current copy right as well as app version name.
<Canvas>
<Story name="Credits">
<VariantsTable titles={[]} columnMinWidth={150}>
<VariantRow variant="Default">
<Credits />
</VariantRow>
</VariantsTable>
</Story>
</Canvas>
@@ -1,87 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react";
import type { ComponentProps } from "react";
import { Dialog, DialogContent, DialogFooter, DialogClose, DialogHeader } from "./Dialog";
type StoryArgs = ComponentProps<typeof Dialog> &
ComponentProps<typeof DialogContent> &
ComponentProps<typeof DialogHeader> &
ComponentProps<typeof DialogFooter> &
ComponentProps<typeof DialogClose> & {
onClick: (...args: unknown[]) => void;
};
const meta: Meta<StoryArgs> = {
component: Dialog,
parameters: {
nextjs: {
appDirectory: true,
},
},
title: "UI/Dialog",
argTypes: {
title: {
control: "text",
},
description: {
control: "text",
},
type: {
options: ["creation", "confirmation"],
control: {
type: "select",
},
},
open: {
control: "boolean",
},
showDivider: {
control: "boolean",
},
disabled: {
control: "boolean",
},
color: {
options: ["minimal", "primary", "secondary", "emphasis"],
control: {
type: "select",
},
},
onClick: { action: "clicked" }, // this is a storybook action addons action
},
render: ({ title, description, type, open, showDivider, disabled, color, onClick }) => (
<Dialog open={open}>
<DialogContent type={type}>
<DialogHeader title={title} subtitle={description} />
<DialogFooter showDivider={showDivider}>
<DialogClose
disabled={disabled}
color={color}
onClick={() => {
const currentUrl = new URL(window.location.href);
currentUrl.searchParams.set("args", "open:false");
window.open(currentUrl.toString(), "_self");
onClick();
}}
/>
</DialogFooter>
</DialogContent>
</Dialog>
),
};
export default meta;
type Story = StoryObj<StoryArgs>;
export const Default: Story = {
name: "Dialog",
args: {
title: "Example Dialog",
description: "Example Dialog Description",
type: "creation",
open: true,
showDivider: false,
disabled: false,
color: "minimal",
},
};
@@ -1,42 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Divider, VerticalDivider } from "./Divider";
<Meta title="UI/Divider" component={Divider} />
<Title title="Divider" suffix="Brief" subtitle="Version 2.0 — Last Update: 05 jan 2023" />
## Definition
Shows the current copy right as well as app version name.
<Canvas>
<Story name="Divider">
<VariantsTable titles={[]} columnMinWidth={150}>
<VariantRow variant="Horizontal">
<div className="dark:text-inverted">
Text above
<Divider />
Text below
</div>
</VariantRow>
<VariantRow variant="Vertical">
<div className="dark:text-inverted flex">
Text left
<VerticalDivider />
Text right
</div>
</VariantRow>
</VariantsTable>
</Story>
</Canvas>
@@ -1,361 +0,0 @@
import { Canvas, Story, Meta } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
CustomArgsTable,
VariantRow,
VariantsTable,
} from "@calcom/storybook/components";
import { Button } from "@calcom/ui/button";
import { Icon } from "@calcom/ui/icon";
import {
Dropdown,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownItem,
DropdownMenuLabel,
DropdownMenuSeparator,
} from "@calcom/ui/dropdown";
<Meta title="UI/Form/Dropdown" component={Dropdown} />
<Title title="Dropdown" suffix="Brief" subtitle="Version 1.0 — Last Update: 29 Aug 2023" />
## Definition
`Dropdown` is an element that displays a menu to the user—such as a set of actions or functions.
## Structure
The `Dropdown` component can be used to display a menu to the user.
<CustomArgsTable of={Dropdown} />
### Dropdown components that have arguments:
#### DropdownMenuTrigger
<CustomArgsTable of={DropdownMenuTrigger} />
#### DropdownMenuContent
<CustomArgsTable of={DropdownMenuContent} />
#### DropdownMenuItem
<CustomArgsTable of={DropdownMenuItem} />
#### DropdownMenuSeparator
<CustomArgsTable of={DropdownMenuSeparator} />
## Examples
<Examples title="Dropdown">
<Example title="Simple">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="No modal">
<Dropdown modal={false}>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
</Examples>
<Examples title="Dropdown Menu Trigger">
<Example title="Simple Button">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="Button Icon">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button StartIcon="plus" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="Disabled">
<Dropdown>
<DropdownMenuTrigger disabled={true} asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="Not as child">
<Dropdown>
<DropdownMenuTrigger>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
</Examples>
<Examples title="Dropdown Menu Content">
<Example title="Custom width">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent style={{ minWidth: "200px" }}>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="Align start">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent style={{ minWidth: "80px" }} align={"start"}>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="Align center">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent style={{ minWidth: "80px" }} align={"center"}>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="With Menu Separator">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="With side offset">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent sideOffset={50}>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
<Example title="With Some icons">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>
<DropdownItem StartIcon="trash">First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem StartIcon="plus">Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<DropdownItem StartIcon="copy">Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
</Examples>
<Examples title="Dropdown Menu Label">
<Example title="Simple">
<Dropdown>
<DropdownMenuTrigger asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align={"start"}>
<DropdownMenuLabel>Number</DropdownMenuLabel>
<DropdownMenuItem>
<DropdownItem>First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem>Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</Example>
</Examples>
## Dropdown Story
<Canvas>
<Story
name="Dropdown"
args={{
asChild: false,
align: "start",
disabled: false,
sideOffset: 0,
}}
argTypes={{
sideOffset: {
control: {
type: "number",
},
},
asChild: {
control: {
type: "boolean",
},
},
align: {
control: {
type: "inline-radio",
options: ["center", "start", "end"],
},
},
disabled: {
control: {
type: "boolean",
},
},
}}>
{({ dir, asChild, sideOffset, align, disabled }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<Dropdown>
<DropdownMenuTrigger disabled={disabled} asChild>
<Button>more</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align={align} sideOffset={sideOffset}>
<DropdownMenuItem>
<DropdownItem StartIcon="trash">First</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem StartIcon="plus">Second</DropdownItem>
</DropdownMenuItem>
<DropdownMenuItem>
<DropdownItem StartIcon="copy">Third</DropdownItem>
</DropdownMenuItem>
</DropdownMenuContent>
</Dropdown>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,68 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
VariantsTable,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Editor } from "./Editor";
<Meta title="UI/Editor" component={Editor} />
<Title title="Editor" suffix="Brief" subtitle="Version 1.0 — Last Update: 16 Aug 2023" />
## Definition
The `Editor` component is a versatile rich text editor that provides a customizable environment for creating and editing content with various formatting options and plugins.
## Structure
The `Editor` component offers a flexible rich text editing interface, complete with a configurable toolbar
<CustomArgsTable of={Editor} />
<Examples title="States">
<Example title="Default">
<Editor setText={() => {}} getText={() => "Text"} />
</Example>
<Example title="With placeholder">
<Editor setText={() => {}} getText={() => ""} placeholder="placeholder" />
</Example>
<Example title="With variables">
<Editor setText={() => {}} getText={() => "Text"} variables={["variable1", "variable2", "variable3"]} />
</Example>
</Examples>
<Title offset title="Editor" suffix="Variants" />
<Canvas>
<Story
name="Editor"
args={{
setText: () => {},
getText: () => "Text",
editable: true,
}}
argTypes={{
excludedToolbarItems: { control: { type: "check", options: ["blockType", "bold", "italic", "link"] } },
variables: { control: { type: "check", options: ["variable1", "variable2", "variable3"] } },
height: { control: { type: "text" } },
placeholder: { control: { type: "text" } },
disableLists: { control: { type: "boolean" } },
updateTemplate: { control: { type: "boolean" } },
firstRender: { control: { type: "boolean" } },
editable: { control: { type: "boolean" } },
}}>
{(props) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<Editor {...props} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,59 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Calendar } from "../icon";
import { EmptyScreen } from "./EmptyScreen";
<Meta title="UI/EmptyScreen" component={EmptyScreen} />
<Title title="EmptyScreen" suffix="Brief" subtitle="Version 2.0 — Last Update: 05 jan 2023" />
## Definition
An empty state is where no info/ apps are added to a page with typically content. There must be a text that prompts users to learn more about why they see this state if necessary.
The CTA button can prompt the user to add the info/ apps needed for the page.
<Canvas>
<Story
name="EmptyScreen"
args={{
headline: "Empty state header",
description:
"Do consectetur qui ex deserunt do est veniam commodo. Eiusmod eiusmod dolore nostrud pariatur mollit sit commodo.",
buttonText: "Learn More",
}}
argTypes={{
headline: {
control: "text",
},
description: {
control: "text",
},
buttonText: {
control: "text",
},
}}>
{({ headline, description, buttonText }) => (
<VariantsTable titles={[]} columnMinWidth={150}>
<VariantRow variant="Default">
<EmptyScreen
Icon="calendar"
headline={headline}
description={description}
buttonText={buttonText}
buttonOnClick={() => alert("Learned More!!")}
/>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,64 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
VariantsTable,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import ErrorBoundary from "./ErrorBoundary";
import { Tooltip } from "../tooltip";
<Meta title="UI/ErrorBoundary" component={ErrorBoundary} />
<Title title="ErrorBoundary" suffix="Brief" subtitle="Version 1.0 — Last Update: 17 Aug 2023" />
## Definition
ErrorBoundary is an element that catches JavaScript errors in their child component tree, log those errors and display a fallback UI.
## Structure
ErrorBoundary offers a flexible component capable of catching JavaScript errors and displaying it in the UI.
<CustomArgsTable of={ErrorBoundary} />
<Examples title="ErrorBoundary">
<Example title="Default">
<ErrorBoundary message="There is a problem with the App">
<p>Child Component</p>
</ErrorBoundary>
</Example>
<Example title="With Error">
<ErrorBoundary message="There is a problem with the App">
<Tooltip />
</ErrorBoundary>
</Example>
</Examples>
<Title offset title="ErrorBoundary" suffix="Variants" />
<Canvas>
<Story
name="ErrorBoundary"
args={{
children: <p class="text-default">Child Component</p>,
message: "There is a problem with the App",
}}>
{({ children, message }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow variant="Default">
<ErrorBoundary message={message}>{children}</ErrorBoundary>
</VariantRow>
<VariantRow variant="With Error">
<ErrorBoundary message={message}>
<Tooltip />
</ErrorBoundary>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,99 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { CheckboxField as Checkbox } from "./Checkbox";
<Meta title="UI/Form/Checkbox" component={Checkbox} />
<Title title="Checkbox " suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Definition
Checkboxes are used in forms and databases to indicate an answer to a question, apply a batch of settings or allow the user to make a multi-selection from a list. Alternatively, a single checkbox may be used for making single selections
## Structure
<CustomArgsTable of={Checkbox} />
<Examples title="Checkbox style">
<Example title="Default">
<Checkbox label="Default" />
</Example>
<Example title="Error">
<Checkbox label="Error" error />
</Example>
<Example title="Disabled">
<Checkbox label="Disabled" disabled />
</Example>
<Example title="Disabled">
<Checkbox label="Disabled Checked" checked disabled />
</Example>
</Examples>
<Examples title="Description As Label">
<Example title="Default">
<Checkbox descriptionAsLabel description="Default Description" />
</Example>
<Example title="Error">
<Checkbox descriptionAsLabel description="Default Description" error />
</Example>
<Example title="Disabled">
<Checkbox descriptionAsLabel description="Default Description" disabled />
</Example>
<Example title="Disabled">
<Checkbox descriptionAsLabel description="Default Description" disabled checked />
</Example>
</Examples>
<Canvas>
<Story
name="Checkbox"
args={{
label: "Default",
description: "Default Description",
error: false,
disabled: false,
}}
argTypes={{
label: {
control: {
type: "text",
},
},
description: {
control: {
type: "text",
},
},
error: {
control: {
type: "boolean",
},
},
disabled: {
control: {
type: "boolean",
},
},
}}>
{({ label, description, error, disabled }) => (
<VariantsTable titles={[""]} columnMinWidth={150}>
<VariantRow variant="Default">
<Checkbox label={label} error={error} disabled={disabled} />
</VariantRow>
<VariantRow variant="Description As Label">
<Checkbox description={description} error={error} disabled={disabled} descriptionAsLabel />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,82 +0,0 @@
import { Tooltip } from "@radix-ui/react-tooltip";
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Example,
Title,
CustomArgsTable,
VariantRow,
VariantsTable,
} from "@calcom/storybook/components";
import ColorPicker from "./colorpicker";
<Meta title="UI/Form/ColorPicker" component={ColorPicker} />
<Title title="ColorPicker" suffix="Brief" subtitle="Version 1.0 — Last Update: 16 Aug 2023" />
## Definitions
`Color Picker` is used to select custom hex colors for from a range of values.
## Structure
The `Color Picker` takes in several props
<CustomArgsTable of={ColorPicker} />
## Default:
<Example title="Default">
<ColorPicker defaultValue="#000000" />
</Example>
## ColorPicker Story
<Canvas>
<Story
name="Default"
args={{
defaultValue: "#21aef3",
onChange: (value) => {
console.debug(value);
},
resetDefaultValue: "#000000",
className: "w-[200px]",
popoverAlign: "start",
}}
argTypes={{
defaultValue: {
control: {
type: "text",
},
},
resetDefaultValue: {
control: {
type: "text",
},
},
popoverAlign: {
control: {
type: "inline-radio",
options: ["center", "start", "end"],
},
},
}}>
{({ defaultValue, onChange, resetDefaultValue, className, popoverAlign }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<Tooltip content="color picker">
<ColorPicker
defaultValue={defaultValue}
onChange={onChange}
resetDefaultValue={resetDefaultValue}
className={className}
popoverAlign={popoverAlign}
/>
</Tooltip>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,100 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
CustomArgsTable,
VariantRow,
VariantsTable,
} from "@calcom/storybook/components";
import { InputFieldWithSelect } from "./InputFieldWithSelect";
import { InputField } from "./TextField";
<Meta title="UI/Form/Input Field" component={InputField} />
<Title title="Inputs" suffix="Brief" subtitle="Version 2.0 — Last Update: 24 Aug 2023" />
## Definition
Text fields allow users to input and edit text into the product. Usually appear in forms and modals. Various options can be shown with the field to communicate the input requirements.## Structure
## Structure
<CustomArgsTable of={InputField} />
<Examples
title="Inputs"
footnote={
<ul>
<li>The width is flexible but the height is fixed for both desktop and mobile. </li>
</ul>
}>
<Example title="Default">
<InputField placeholder="Default" />
</Example>
</Examples>
<Examples title="Input Types">
<Example title="Default">
<InputField placeholder="Default" />
</Example>
<Example title="Prefix">
<InputField placeholder="Prefix" addOnLeading={<>Prefix</>} />
</Example>
<Example title="Suffix">
<InputField placeholder="Suffic" addOnSuffix={<>Suffix</>} />
</Example>
<Example title="Suffix With Select">
<InputFieldWithSelect
placeholder="Suffix"
selectProps={{ options: [{ value: "TEXT", label: "Text" }] }}
/>
</Example>
<Example title="Focused">
<InputField placeholder="Focused" className="sb-pseudo--focus" />
</Example>
<Example title="Hovered">
<InputField placeholder="Hovered" className="sb-pseudo--hover" />
</Example>
<Example title="Error">
<InputField placeholder="Error" error="Error" />
</Example>
</Examples>
<Examples title="Input Text">
<Example title="Default">
<InputField />
</Example>
<Example title="Placeholder">
<InputField placeholder="Placeholder" />
</Example>
<Example title="Filled">
<InputField value="Filled" />
</Example>
</Examples>
<Title offset title="Input" suffix="Variants" />
<Canvas>
<Story name="All Variants">
<VariantsTable titles={["Default", "Focused", "Hovered"]} columnMinWidth={150}>
<VariantRow variant="Default">
<InputField placeholder="Default" />
<InputField placeholder="Focused" className="sb-pseudo--focus" />
<InputField placeholder="Hovered" className="sb-pseudo--hover" />
</VariantRow>
<VariantRow variant="Prefixed">
<InputField placeholder="Default" addOnLeading={<>Prefix</>} />
<InputField placeholder="Focused" className="sb-pseudo--focus" addOnLeading={<>Prefix</>} />
<InputField placeholder="Hovered" className="sb-pseudo--hover" addOnLeading={<>Prefix</>} />
</VariantRow>
<VariantRow variant="Suffix">
<InputField placeholder="Default" addOnSuffix={<>Prefix</>} />
<InputField placeholder="Focused" className="sb-pseudo--focus" addOnSuffix={<>Prefix</>} />
<InputField placeholder="Hovered" className="sb-pseudo--hover" addOnSuffix={<>Prefix</>} />
</VariantRow>
</VariantsTable>
</Story>
</Canvas>
@@ -1,129 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
CustomArgsTable,
VariantRow,
VariantsTable,
} from "@calcom/storybook/components";
import { SelectField } from "./Select";
<Meta title="UI/Form/Select Field" component={SelectField} />
<Title title="Select" suffix="Brief" subtitle="Version 2.0 — Last Update: 29 Aug 2022" />
## Definition
Dropdown fields allow users to input existing options that is preset by the designer/developer. It can be just one choice per field, or they might be multiple choices depends on the circumstances.
## Structure
<CustomArgsTable of={SelectField} />
export const options = [
{ value: 0, label: "Option One" },
{ value: 1, label: "Option Two" },
{ value: 3, label: "Option Three" },
{ value: 4, label: "Option Four" },
];
## Examples
<Examples
title=" Single Selected / Unselected"
footnote={
<ul>
<li>The difference between the types are when they are filled. </li>
</ul>
}>
<Example title="Single Select [Unselected]" isFullWidth>
<SelectField label={"Single Select"} options={options} />
</Example>
<Example title="Single Select [Selected]" isFullWidth>
<SelectField label={"Single Select"} options={options} defaultValue={options[0]} />
</Example>
<Example title="Multi Select [Unselected]" isFullWidth>
<SelectField label={"Multi Select"} options={options} isMulti={true} />
</Example>
<Example title="Multi Select [Selected]" isFullWidth>
<SelectField label={"Multi Select"} options={options} isMulti={true} defaultValue={options[0]} />
</Example>
</Examples>
<Examples title="Variants">
<Example title="Default">
<SelectField label={"Default Select"} options={options} />
</Example>
<Example title="Icon Left">
WIP
{/* <SelectField options={options} components={{ Control }}/> */}
</Example>
</Examples>
## Variant Caviats (WIP) - To be updated
Using Icons is a bit of a strange one cause you can't simpily pass in an icon as a prop. You have to pass in a component. To the select field.
```js
// Bad: Inline declaration will cause remounting issues
const BadSelect = (props) => (
<Select
{...props}
components={{
Control: ({ children, ...rest }) => <components.Control {...rest}>👎 {children}</components.Control>,
}}
/>
);
// Good: Custom component declared outside of the Select scope
const Control = <IconLeading icon="plus" />;
const GoodSelect = (props) => <Select {...props} components={{ Control }} />;
```
<Examples title="States ">
<Example title="Default">
<SelectField options={options} label={"Default Select"} />
</Example>
{/* <Example title="Hover">
<SelectField options={options} className="sb-pseudo--hover"/>
</Example>
<Example title="Focus">
<SelectField options={options} className="sb-pseudo--focus"/>
</Example> */}
</Examples>
## Select Story
<Canvas>
<Story
name="Default"
args={{
required: false,
name: "select-field",
error: "Some error",
variant: "default",
label: "Select an item",
isMulti: false,
options,
}}
argTypes={{
variant: {
control: {
type: "select",
options: ["default", "checkbox"],
},
},
}}>
{(args) => (
<VariantsTable titles={["Default"]} columnMinWidth={300}>
<VariantRow>
<SelectField {...args} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,43 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { Title, VariantRow, VariantsTable, CustomArgsTable } from "@calcom/storybook/components";
import { Steps } from "./Steps";
<Meta title="UI/Form/Steps" component={Steps} />
<Title title="Steps" suffix="Brief" subtitle="Version 1.0 — Last Update: 15 Aug 2023" />
## Definition
Steps component is used to display the current step out of the total steps in a process.
## Structure
The `Steps` component can be used to show the steps of the total in a process.
<CustomArgsTable of={Steps} />
## Steps Story
<Canvas>
<Story
name="Steps"
args={{ maxSteps: 4, currentStep: 2 }}
argTypes={{ maxSteps: { control: "number" }, currentStep: { control: "number" } }}>
{({ maxSteps, currentStep }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<Steps
maxSteps={maxSteps}
currentStep={currentStep}
navigateToStep={(step) => {
const newPath = `?path=/story/ui-form-steps--steps&args=currentStep:${step + 1}`;
window.open(newPath, "_self");
}}
/>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,97 +0,0 @@
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
VariantsTable,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import Switch from "./Switch";
<Meta title="UI/Form/Switch" component={Switch} />
<Title title="Switch" suffix="Brief" subtitle="Version 1.0 — Last Update: 16 Aug 2023" />
## Definition
Switch is a customizable toggle switch component that allows users to change between two states.
## Structure
The `Switch` component can be used to create toggle switches for various purposes. It provides options for adding labels, icons, and tooltips.
<CustomArgsTable of={Switch} />
<Examples title="States">
<Example title="Default">
<Switch />
</Example>
<Example title="Disabled">
<Switch disabled />
</Example>
<Example title="Checked">
<Switch checked />
</Example>
</Examples>
<Examples title="Labels">
<Example title="With Label and labelOnLeading">
<Switch label="Enable Feature" labelOnLeading />
</Example>
<Example title="With Label">
<Switch label="Enable Feature" />
</Example>
</Examples>
<Examples title="Hover">
<Example title="With Tooltip (Hover me)">
<TooltipProvider>
<Switch tooltip="Toggle to enable/disable the feature" />
</TooltipProvider>
</Example>
<Example title="Without Tooltip (Hover me)">
<TooltipProvider>
<Switch />
</TooltipProvider>
</Example>
</Examples>
<Title offset title="Switch" suffix="Variants" />
<Canvas>
<Story
name="Switch"
args={{
label: "Enable Feature",
tooltip: "Toggle to enable/disable the feature",
checked: false,
disabled: false,
fitToHeight: false,
labelOnLeading: false,
}}
argTypes={{
label: { control: { type: "text" } },
tooltip: { control: { type: "text" } },
checked: { control: { type: "boolean" } },
disabled: { control: { type: "boolean" } },
fitToHeight: { control: { type: "boolean" } },
labelOnLeading: { control: { type: "boolean" } },
}}>
{(props) => (
<TooltipProvider>
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<Switch
{...props}
onCheckedChange={(checkedValue) => console.log("Switch value:", checkedValue)}
/>
</VariantRow>
</VariantsTable>
</TooltipProvider>
)}
</Story>
</Canvas>
@@ -1,83 +0,0 @@
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
CustomArgsTable,
Examples,
Example,
Title,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { StorybookTrpcProvider } from "../../mocks/trpc";
import { TimezoneSelect } from "./TimezoneSelect";
<Meta title="UI/Form/TimezoneSelect" component={TimezoneSelect} />
<Title title="TimezoneSelect" suffix="Brief" subtitle="Version 1.0 — Last Update: 25 Aug 2023" />
## Definition
The `TimezoneSelect` component is used to display timezone options.
## Structure
The `TimezoneSelect` component can be used to display timezone options.
<CustomArgsTable of={TimezoneSelect} />
## Examples
<Examples title="TimezoneSelect">
<Example title="Default">
<StorybookTrpcProvider>
<TimezoneSelect value="Africa/Douala" />
</StorybookTrpcProvider>
</Example>
<Example title="Disabled">
<StorybookTrpcProvider>
<TimezoneSelect value="Africa/Douala" isDisabled />
</StorybookTrpcProvider>
</Example>
</Examples>
## TimezoneSelect Story
<Canvas>
<Story
name="TimezoneSelect"
args={{
className: "mt-24",
value: "Africa/Douala",
variant: "default",
isDisabled: false,
timezones: {
"Timezone 1": "City 1",
"Timezone 2": "City 2",
"Timezone 3": "City 3",
},
isPending: false,
}}
argTypes={{
value: {
control: { disable: true },
},
variant: {
control: {
type: "inline-radio",
options: ["default", "minimal"],
},
},
}}>
{(args) => (
<VariantsTable titles={["Default"]} columnMinWidth={350}>
<VariantRow>
<StorybookTrpcProvider>
<TimezoneSelect {...args} />
</StorybookTrpcProvider>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,108 +0,0 @@
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
CustomArgsTable,
Examples,
Example,
Title,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Icon } from "@calcom/ui/icon";
import { ToggleGroup } from "./ToggleGroup";
<Meta title="UI/Form/ToggleGroup" component={ToggleGroup} />
<Title title="ToggleGroup" suffix="Brief" subtitle="Version 1.0 — Last Update: 17 Aug 2023" />
## Definition
The `ToggleGroup` component is used to create a group of toggle items with optional tooltips.
## Structure
<CustomArgsTable of={ToggleGroup} />
## Examples
<Examples title="Toggle Group With Icon Left">
<Example>
<TooltipProvider>
<ToggleGroup
options={[
{ value: "option1", label: "Option 1", tooltip: "Tooltip for Option 1", iconLeft: <Icon name="arrow-right" /> },
{ value: "option2", label: "Option 2", iconLeft: <Icon name="arrow-right" /> },
{ value: "option3", label: "Option 3", iconLeft: <Icon name="arrow-right" /> },
{
value: "option4",
label: "Option 4",
tooltip: "Tooltip for Option 4",
iconLeft: <Icon name="arrow-right" />,
},
{ value: "option5", label: "Option 5", iconLeft: <Icon name="arrow-right" />, disabled: true },
]}
/>
</TooltipProvider>
</Example>
</Examples>
## ToggleGroup Story
<Canvas>
<Story
name="Default"
args={{
options: [
{ value: "option1", label: "Option 1", tooltip: "Tooltip for Option 1" },
{ value: "option2", label: "Option 2" },
{ value: "option3", label: "Option 3" },
{
value: "option4",
label: "Option 4",
tooltip: "Tooltip for Option 4",
},
{ value: "option5", label: "Option 5", disabled: true },
],
}}
argTypes={{
options: {
value: {
control: {
type: "text",
},
},
label: {
control: {
type: "text",
},
},
tooltip: {
control: {
type: "text",
},
},
disabled: {
control: {
type: "boolean",
},
},
isFullWidth: {
control: {
type: "boolean",
},
},
},
}}>
{({ options, isFullWidth }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<TooltipProvider>
<ToggleGroup options={options} isFullWidth={isFullWidth} />
</TooltipProvider>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,63 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { CustomArgsTable, Title, VariantsTable, VariantRow } from "@calcom/storybook/components";
import WizardForm from "./WizardForm";
<Meta title="UI/Form/WizardForm" component={WizardForm} />
<Title title="WizardForm" subtitle="Version 1.0 — Last Update: 5 Sep 2023" />
## Definition
The `WizardForm` component provides a structure for creating multi-step forms or wizards.
## Structure
<CustomArgsTable of={WizardForm} />
## Note on Navigation
Please be aware that the steps navigation is managed internally within the `WizardForm` component. As such, when viewing this component in Storybook, clicking the "Next" button will not showcase the transition to the subsequent step.
To observe the actual step navigation behavior, please refer to the Storybook stories for the individual `Steps` component.
## WizardForm Story
<Canvas>
<Story
parameters={{
nextjs: {
appDirectory: true,
},
}}
name="Basic"
args={{
href: "/wizard",
steps: [
{ title: "Step 1", description: "Description for Step 1" },
{ title: "Step 2", description: "Description for Step 2" },
{ title: "Step 3", description: "Description for Step 3" },
],
}}
argTypes={{
href: {
control: {
type: "text",
},
},
steps: {
control: {
type: "object",
},
},
}}>
{({ href, steps }) => (
<VariantsTable titles={["Basic Wizard Form"]} columnMinWidth={150}>
<VariantRow>
<WizardForm href={href} steps={steps} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,62 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { Title, VariantRow, VariantsTable, CustomArgsTable } from "@calcom/storybook/components";
import ImageUploader from "./ImageUploader";
<Meta title="UI/ImageUploader" component={ImageUploader} />
<Title title="ImageUploader" suffix="Brief" subtitle="Version 1.0 — Last Update: 21 Aug 2023" />
## Definitions
`ImageUploader` is used to upload images of all image types
## Structure
Below are the props for `Image uploader`
<CustomArgsTable of={ImageUploader} />
## ImageUploader Story
<Canvas>
<Story
parameters={{
nextjs: {
appDirectory: true,
},
}}
name="ImageUploader"
play={({ canvasElement }) => {
const darkVariantContainer = canvasElement.querySelector("#dark-variant");
const imageUploaderElement = darkVariantContainer.querySelector("button");
imageUploaderElement?.addEventListener("click", () => {
setTimeout(() => {
document.querySelector('[role="dialog"]')?.classList.add("dark");
}, 1);
});
}}
args={{
id: "image-1",
buttonMsg: "upload",
target: "target",
handleAvatarChange: (src) => {
console.debug(src);
},
}}>
{({ id, buttonMsg, handleAvatarChange, imageSrc, target }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<ImageUploader
id={id}
buttonMsg={buttonMsg}
handleAvatarChange={handleAvatarChange}
imageSrc={imageSrc}
target={target}
/>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,83 +0,0 @@
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
VariantsTable,
VariantColumn,
RowTitles,
CustomArgsTable,
} from "@calcom/storybook/components";
import { Tooltip } from "../tooltip";
<Meta title="Layout/Spacing" />
<Title title="Spacing" suffix="Brief" subtitle="Version 2.0 — Last Update: 15 Feb 2023" />
## Definition
Defines the spacing guide used in Cal.coms design system
## Structure
<Examples title="Spacing">
<TooltipPrimitive.Provider>
<div className="flex flex-row gap-6">
<Example title="0"></Example>
<Example title="px">
<Tooltip content="1px">
<div className="bg-inverted h-4 w-px rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="0.5">
<Tooltip content="2px">
<div className="bg-inverted h-4 w-0.5 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="1">
<Tooltip content="4px">
<div className="bg-inverted h-4 w-1 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="2">
<Tooltip content="8px">
<div className="bg-inverted h-4 w-2 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="3">
<Tooltip content="12px">
<div className="bg-inverted h-4 w-3 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="4">
<Tooltip content="16px">
<div className="bg-inverted h-4 w-4 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="5">
<Tooltip content="20px">
<div className="bg-inverted h-4 w-5 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="6">
<Tooltip content="24px">
<div className="bg-inverted h-4 w-6 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="8">
<Tooltip content="32px">
<div className="bg-inverted h-4 w-8 rounded-sm"> </div>
</Tooltip>
</Example>
<Example title="10">
<Tooltip content="48px">
<div className="bg-inverted h-4 w-10 rounded-sm"> </div>
</Tooltip>
</Example>
</div>
</TooltipPrimitive.Provider>
</Examples>
@@ -1,97 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { List, ListItem, ListItemTitle, ListItemText } from "./List";
export const listItems = [
{ title: "Title 1", description: "Description 1" },
{ title: "Title 2", description: "Description 2" },
{ title: "Title 3", description: "Description 3" },
];
<Meta title="UI/List" component={List} />
<Title title="List" suffix="Brief" subtitle="Version 2.0 — Last Update: 24 Aug 2023" />
## Definition
The List component is used to render an unordered list with default styling
## Structure
List takes an array of objects to display a list in the UI
### List
<CustomArgsTable of={List} />
### ListItem
<CustomArgsTable of={ListItem} />
<Examples>
<Example title="Default">
<List>
{listItems.map((item) => (
<ListItem rounded={false}>
<ListItemTitle className="mr-2">{item.title}</ListItemTitle>
<ListItemText>{item.description}</ListItemText>
</ListItem>
))}
</List>
</Example>
<Example title="Round Container">
<List roundContainer={false}>
{listItems.map((item) => (
<ListItem rounded={false}>
<ListItemTitle className="mr-2">{item.title}</ListItemTitle>
<ListItemText>{item.description}</ListItemText>
</ListItem>
))}
</List>
</Example>
<Example title="No Border Treatment">
<List noBorderTreatment={true}>
{listItems.map((item) => (
<ListItem rounded={false}>
<ListItemTitle className="mr-2">{item.title}</ListItemTitle>
<ListItemText>{item.description}</ListItemText>
</ListItem>
))}
</List>
</Example>
</Examples>
<Title offset title="List" suffix="Variants" />
<Canvas>
<Story
name="List"
args={{
roundContainer: true,
noBorderTreatment: false,
rounded: false,
expanded: false
}}>
{({ roundContainer, noBorderTreatment, rounded, expanded }) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<List roundContainer={roundContainer} noBorderTreatment={noBorderTreatment}>
{listItems.map((item) => (
<ListItem rounded={rounded} expanded={expanded}>
<ListItemTitle className="mr-2">{item.title}</ListItemTitle>
<ListItemText>{item.description}</ListItemText>
</ListItem>
))}
</List>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,54 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import Logo from "./Logo";
<Meta title="UI/Logo" component={Logo} />
<Title title="Logo" suffix="Brief" subtitle="Version 2.0 — Last Update: 28 Aug 2023" />
## Definition
Main Cal.com brand logo
<CustomArgsTable of={Logo} />
## Examples
<Examples>
<Example title="Default">
<Logo src={"https://app.cal.com/api/logo"} />
</Example>
<Example title="Small">
<Logo src={"https://app.cal.com/api/logo"} small />
</Example>
<Example title="As an Icon">
<Logo src={"https://app.cal.com/api/logo"} icon />
</Example>
</Examples>
<Canvas>
<Story
name="Logo"
args={{
icon: false,
src: "https://app.cal.com/api/logo",
small: false,
}}>
{(args) => (
<VariantsTable titles={[""]} columnMinWidth={150}>
<VariantRow>
<Logo {...args} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
-27
View File
@@ -1,27 +0,0 @@
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useState, type PropsWithChildren } from "react";
import type { AppRouter } from "@calcom/trpc/server/routers/_app";
import { httpBatchLink } from "@trpc/client";
import { createTRPCReact } from "@trpc/react-query";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const mockedTrpc: any = createTRPCReact<AppRouter>();
export const StorybookTrpcProvider = ({ children }: PropsWithChildren) => {
const [queryClient] = useState(new QueryClient({ defaultOptions: { queries: { staleTime: Infinity } } }));
const [trpcClient] = useState(() =>
mockedTrpc.createClient({
links: [httpBatchLink({ url: "" })],
})
);
return (
<mockedTrpc.Provider client={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
</mockedTrpc.Provider>
);
};
@@ -1,134 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs/blocks";
import {
Title,
VariantRow,
VariantsTable,
CustomArgsTable,
Examples,
Example,
} from "@calcom/storybook/components";
import { Icon } from "@calcom/ui/icon";
import HorizontalTabs from "../HorizontalTabs";
<Meta title="UI/Navigation/HorizontalTabs" component={HorizontalTabs} />
<Title title="Horizontal Tabs" suffix="Brief" subtitle="Version 1.0 — Last Update: 17 Aug 2023" />
## Definition
The HorizontalTabs component is a user interface element used for displaying a horizontal set of tabs, often employed for navigation or organization purposes within a web application.
## Structure
The HorizontalTabs component is designed to work alongside the HorizontalTabItem component, which represents individual tabs within the tab bar.
export const tabs = [
{
name: "Tab 1",
href: "?path=/story/ui-navigation-horizontaltabs--horizontal-tabs/tab1",
disabled: false,
linkShallow: true,
linkScroll: true,
icon: Plus,
},
{
name: "Tab 2",
href: "?path=/story/ui-navigation-horizontaltabs--horizontal-tabs/tab2",
disabled: false,
linkShallow: true,
linkScroll: true,
avatar: "Avatar",
},
{
name: "Tab 3",
href: "?path=/story/ui-navigation-horizontaltabs--horizontal-tabs/tab3",
disabled: true,
linkShallow: true,
linkScroll: true,
},
];
<CustomArgsTable of={HorizontalTabs} />
<Examples title="Default">
<Example title="Default">
<HorizontalTabs
tabs={[
{
name: "tab 1",
href: "?path=/story/ui-navigation-horizontaltabs--horizontal-tabs/tab1",
},
]}
/>
</Example>
<Example title="With avatar">
<HorizontalTabs
tabs={[
{
name: "Tab 1",
href: "?path=/story/ui-navigation-horizontaltabs--horizontal-tabs/tab1",
avatar: "Avatar",
},
]}
/>
</Example>
<Example title="With icon">
<HorizontalTabs
tabs={[
{
name: "Tab 1",
href: "?path=/story/ui-navigation-horizontaltabs--horizontal-tabs/tab1",
icon: Plus,
},
]}
/>
</Example>
<Example title="Disabled">
<HorizontalTabs
tabs={[
{
name: "Tab 1",
href: "?path=/story/ui-navigation-horizontaltabs--horizontal-tabs/tab1",
disabled: true,
},
]}
/>
</Example>
</Examples>
## HorizontalTabs Story
<Canvas>
<Story
name="Horizontal Tabs"
args={{
name: "Tab 1",
href: "/tab1",
disabled: false,
className: "",
linkShallow: true,
linkScroll: true,
icon: "",
avatar: "",
}}
argTypes={{
name: { control: "text", description: "Tab name" },
href: { control: "text", description: "Tab link" },
disabled: { control: "boolean", description: "Whether the tab is disabled" },
className: { control: "text", description: "Additional CSS class" },
linkShallow: { control: "boolean", description: "Whether to use shallow links" },
linkScroll: { control: "boolean", description: "Whether to scroll to links" },
icon: { control: "text", description: "SVGComponent icon" },
avatar: { control: "text", description: "Avatar image URL" },
}}>
{(...props) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<HorizontalTabs tabs={tabs} className="overflow-hidden" actions={<button>Click me</button>} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,158 +0,0 @@
import { Meta, Story, Canvas } from "@storybook/addon-docs/blocks";
import {
Title,
CustomArgsTable,
Examples,
Example,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Icon } from "@calcom/ui/icon";
import VerticalTabs from "../VerticalTabs";
<Meta title="UI/Navigation/VerticalTabs" component={VerticalTabs} />
<Title title="Vertical Tabs Brief" subtitle="Version 1.0 — Last Update: 17 Aug 2023" />
## Definition
The VerticalTabs component is a user interface element utilized to present a vertical set of tabs, commonly employed for navigation or organizing content within a web application.
## Structure
The VerticalTabs component is designed to complement the HorizontalTabItem component, which represents individual tabs within the tab bar. This combination allows for creating intuitive navigation experiences and organized content presentation.
export const tabs = [
{
name: "Tab 1",
href: "/tab1",
disabled: false,
linkShallow: true,
linkScroll: true,
disableChevron: true,
icon: Plus,
},
{
name: "Tab 2",
href: "/tab2",
disabled: false,
linkShallow: true,
linkScroll: true,
avatar: "Avatar",
},
{
name: "Tab 3",
href: "/tab3",
disabled: true,
linkShallow: true,
linkScroll: true,
},
];
<CustomArgsTable of={VerticalTabs} />
<Examples title="Default">
<Example title="Default">
<VerticalTabs
tabs={[
{
name: "tab 1",
href: "/tab1",
},
]}
/>
</Example>
<Example title="Disabled chevron">
<VerticalTabs
tabs={[
{
name: "Tab 1",
href: "/tab1",
disableChevron: true,
},
]}
/>
</Example>
<Example title="With icon">
<VerticalTabs
tabs={[
{
name: "Tab 1",
href: "/tab1",
icon: Plus,
},
]}
/>
</Example>
<Example title="Disabled">
<VerticalTabs
tabs={[
{
name: "Tab 1",
href: "/tab1",
disabled: true,
},
]}
/>
</Example>
</Examples>
## VerticalTabs Story
<Canvas>
<Story
name="Vertical Tabs"
args={{
name: "Tab 1",
info: "Tab information",
icon: Plus,
disabled: false,
children: [
{
name: "Sub Tab 1",
href: "/sub-tab1",
disabled: false,
className: "sub-tab",
},
],
textClassNames: "",
className: "",
isChild: false,
hidden: false,
disableChevron: true,
href: "/tab1",
isExternalLink: true,
linkShallow: true,
linkScroll: true,
avatar: "",
iconClassName: "",
}}
argTypes={{
name: { control: "text", description: "Tab name" },
info: { control: "text", description: "Tab information" },
icon: { control: "object", description: "SVGComponent icon" },
disabled: { control: "boolean", description: "Whether the tab is disabled" },
children: { control: "object", description: "Array of child tabs" },
textClassNames: { control: "text", description: "Additional text class names" },
className: { control: "text", description: "Additional CSS class" },
isChild: { control: "boolean", description: "Whether the tab is a child tab" },
hidden: { control: "boolean", description: "Whether the tab is hidden" },
disableChevron: { control: "boolean", description: "Whether to disable the chevron" },
href: { control: "text", description: "Tab link" },
isExternalLink: { control: "boolean", description: "Whether the link is external" },
linkShallow: { control: "boolean", description: "Whether to use shallow links" },
linkScroll: { control: "boolean", description: "Whether to scroll to links" },
avatar: { control: "text", description: "Avatar image URL" },
iconClassName: { control: "text", description: "Additional icon class name" },
}}>
{(...props) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<VerticalTabs tabs={tabs} className="overflow-hidden" />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,138 +0,0 @@
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { Fragment } from "react";
import { FilterCheckboxFieldsContainer } from "@calcom/features/filters/components/TeamsFilter";
import {
CustomArgsTable,
Examples,
Example,
Title,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Button, CheckboxField } from "@calcom/ui";
import { List, ListItem } from "../list";
import { AnimatedPopover } from "./AnimatedPopover";
<Meta title="UI/Popover" component={AnimatedPopover} />
<Title title="Popover" suffix="Brief" subtitle="Version 1.0 — Last Update: 29 Aug 2023" />
## Definition
The `Popover` component is used to display rich content in a portal.
## Structure
The `Popover` component can be used to display a rich content in a portal.
<CustomArgsTable of={AnimatedPopover} />
## Examples
<Examples>
<Example title="Default">
<TooltipProvider>
<AnimatedPopover text="Go">
<FilterCheckboxFieldsContainer>
{["First", "Second", "Third"]?.map((eventType) => (
<div key={eventType.value} className="items-center hover:bg-muted flex cursor-pointer px-4 py-2">
<CheckboxField
checked={false}
onChange={(e) => {
console.log("changed ", e);
}}
description={eventType}
/>
</div>
))}
</FilterCheckboxFieldsContainer>
</AnimatedPopover>
</TooltipProvider>
</Example>
<Example title="With Trigger">
<TooltipProvider>
<AnimatedPopover text="Go" Trigger={<button>click here</button>}>
<FilterCheckboxFieldsContainer>
{["First", "Second", "Third"]?.map((eventType) => (
<div key={eventType.value} className="items-center hover:bg-muted flex cursor-pointer px-4 py-2">
<CheckboxField
checked={false}
onChange={(e) => {
console.log("changed ", e);
}}
description={eventType}
/>
</div>
))}
</FilterCheckboxFieldsContainer>
</AnimatedPopover>
</TooltipProvider>
</Example>
<Example title="With count">
<TooltipProvider>
<AnimatedPopover text="Go here" count={1}>
<FilterCheckboxFieldsContainer>
{["First", "Second", "Third"]?.map((eventType) => (
<div key={eventType.value} className="items-center hover:bg-muted flex cursor-pointer px-4 py-2">
<CheckboxField
checked={false}
onChange={(e) => {
console.log("changed ", e);
}}
description={eventType}
/>
</div>
))}
</FilterCheckboxFieldsContainer>
</AnimatedPopover>
</TooltipProvider>
</Example>
</Examples>
## Popover Story
<Canvas>
<Story
name="Popover"
args={{
text: "Go",
childrenText: "Here is it",
defaultOpen: false,
}}
argTypes={{
count: {
control: {
type: "number",
},
},
}}>
{({ text, childrenText, count, defaultOpen }) => (
<VariantsTable titles={["Default"]} columnMinWidth={50}>
<VariantRow>
<TooltipProvider>
<AnimatedPopover text={text} count={count} defaultOpen={defaultOpen}>
<FilterCheckboxFieldsContainer>
{["First", "Second", "Third"]?.map((eventType) => (
<div
key={eventType.value}
className="items-center hover:bg-muted flex cursor-pointer px-4 py-2">
<CheckboxField
checked={false}
onChange={(e) => {
console.log("changed ", e);
}}
description={eventType}
/>
</div>
))}
</FilterCheckboxFieldsContainer>
</AnimatedPopover>
</TooltipProvider>
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,53 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
VariantsTable,
VariantColumn,
RowTitles,
CustomArgsTable,
} from "@calcom/storybook/components";
import { Button } from "../button";
import {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "./Sheet";
<Meta title="UI/Sheet" />
<Title title="Sheet" suffix="Brief" subtitle="Version 2.0 — Last Update: 21 June 2023" />
## Definition
A sheet is a container that can be used to display content on different sides of the current page.
## Structure
<Examples title="Spacing">
<Sheet>
<SheetTrigger asChild>
<Button>Open default sheet</Button>
</SheetTrigger>
<SheetContent position="right" size={"default"}>
<SheetHeader>
<SheetTitle>Edit profile</SheetTitle>
<SheetDescription>Make changes to your profile here. Click save when you're done.</SheetDescription>
</SheetHeader>
<SheetFooter>
<SheetClose asChild>
<Button type="submit">Save changes</Button>
</SheetClose>
</SheetFooter>
</SheetContent>
</Sheet>
</Examples>
@@ -1,44 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
VariantsTable,
VariantColumn,
RowTitles,
CustomArgsTable,
} from "@calcom/storybook/components";
import { Skeleton, SkeletonAvatar, SkeletonText, SkeletonButton, SkeletonContainer } from "./";
<Meta title="UI/Skeleton" component={Skeleton} />
<Title title="Skeleton" suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Definition
Skeletons are used as a placeholder to the content while the content is being loaded. It is used to improve the user experience by providing a visual cue that the content is loading.
## Structure
<CustomArgsTable of={Skeleton} />
<Examples title="Skeleton Avatar">
<Example title="Primary">
<SkeletonAvatar className="h-8 w-8" />
</Example>
</Examples>
<Examples title="Skeleton Text">
<Example title="Primary">
<SkeletonText className="h-4 w-32" />
</Example>
</Examples>
<Examples title="Skeleton Button">
<Example title="Primary">
<SkeletonButton className="h-8 w-32" />
</Example>
</Examples>
@@ -1,48 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
VariantsTable,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import { Table } from "./Table";
import { TableExampleComponent } from "./TableExamples";
<Meta title="UI/Table/Table" component={Table} />
<Title title="Table" suffix="Brief" subtitle="Version 1.0 — Last Update: 21 Aug 2023" />
## Definition
The `Table` component is a HTML table that utilizes Tailwind classes to enhance its styles.
## Structure
The `Table` component should be used with other table sub-components (present as object attributes) that follow the same pattern.
These components render common elements that are styled with Tailwind. These components include:
- `Body` -> (`tbody`)
- `Header` -> (`thead`)
- `Row` -> (`tr`)
- `ColumnTitle` -> (`th`)
- `Cell` -> (`td`)
<CustomArgsTable of={Table} />
<Title offset title="Table" suffix="Variants" />
<Canvas>
<Story name="Table">
{(props) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<TableExampleComponent />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,50 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import {
Examples,
Example,
Title,
VariantsTable,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import { TableNewExampleComponent } from "./TableExamples";
import { Table } from "./TableNew";
<Meta title="UI/Table/TableNew" component={Table} />
<Title title="Table New" suffix="Brief" subtitle="Version 1.0 — Last Update: 21 Aug 2023" />
## Definition
The `Table` component (from TableNew.tsx) is a HTML table that utilizes Tailwind classes to enhance its styles.
## Structure
The `Table` component should be used with other table sub-components (exported in the same file) that follow the same pattern.
These components render common elements that are styled with Tailwind. These components include:
- `TableBody` -> (`tbody`)
- `TableHeader` -> (`thead`)
- `TableRow` -> (`tr`)
- `TableHead` -> (`th`)
- `TableCell` -> (`td`)
- `TableFooter` -> (`tfoot`)
- `TableCaption` -> (`caption`)
<CustomArgsTable of={Table} />
<Title offset title="Table New" suffix="Variants" />
<Canvas>
<Story name="Table New">
{(props) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<TableNewExampleComponent />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,62 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
VariantsTable,
VariantColumn,
RowTitles,
CustomArgsTable,
VariantRow,
} from "@calcom/storybook/components";
import { SuccessToast, ErrorToast, WarningToast } from "./";
<Meta title="UI/Toasts" component={SuccessToast} />
<Title title="Toasts" suffix="Brief" subtitle="Version 2.0 — Last Update: 22 Aug 2022" />
## Definition
Toasts are used to show an action has had a impact. If a user submits a form a toast should be shown to notify the user there has been a success
## Structure
<CustomArgsTable of={SuccessToast} />
<Examples title="Toasts">
<Example title="Success">
<SuccessToast message="Success Toast" />
</Example>
<Example title="Warning">
<WarningToast message="Warning Toast" />
</Example>
<Example title="Error">
<ErrorToast message="Error Toast" />
</Example>
</Examples>
## Toast Story
<Canvas>
<Story
name="Toast Variants"
args={{
message: "Toast Message",
}}
argTypes={{
message: { control: "text" },
}}>
{({ message, toastVisible }) => (
<VariantsTable titles={["Success", "Warning", "Error"]} columnMinWidth={150}>
<VariantRow variant="Success">
<SuccessToast message={message} />
<WarningToast message={message} />
<ErrorToast message={message} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
@@ -1,20 +0,0 @@
import { Canvas, Meta } from "@storybook/blocks";
import { Title, CustomArgsTable } from "@calcom/storybook/components";
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { Tooltip } from "./Tooltip";
import * as TooltipStories from "./Tooltip.stories";
<Meta of={TooltipStories} />
<Title title="Tooltip" suffix="Brief" subtitle="Version 2.0 — Last Update: 06 Jan 2023" />
## Definition
Tooltip components can be used to provide additional information about an element when the user hovers over or focuses on the element.
<TooltipProvider>
<CustomArgsTable of={Tooltip} />
</TooltipProvider>
<Canvas of={TooltipStories.Default}/>
@@ -1,37 +0,0 @@
import type { Meta, StoryObj } from "@storybook/react";
import { VariantRow, VariantsTable } from "@calcom/storybook/components";
import { Tooltip } from "./Tooltip";
const meta: Meta<typeof Tooltip> = {
component: Tooltip,
title: "UI/Tooltip",
};
export default meta;
type Story = StoryObj<typeof Tooltip>;
export const Default: Story = {
name: "Tooltip",
parameters: {
hoverMsg: "Click to copy",
alertMsg: "Copied!",
content: "Copy me!",
},
render: (_, { parameters: { content, hoverMsg, alertMsg } }) => (
<VariantsTable titles={[]}>
<VariantRow variant="Default">
<Tooltip content={`${hoverMsg}`}>
<span
className="dark:text-darkgray-50 bg-brand-default dark:bg-darkgray-900 rounded-md p-2 text-gray-100 hover:cursor-pointer"
onClick={() => {
alert(`${alertMsg}`);
}}>
{content}
</span>
</Tooltip>
</VariantRow>
</VariantsTable>
),
};
@@ -1,113 +0,0 @@
import { Canvas, Meta, Story, ArgsTable } from "@storybook/addon-docs";
import {
Examples,
Example,
Note,
Title,
CustomArgsTable,
VariantsTable,
VariantRow,
} from "@calcom/storybook/components";
import { TopBanner } from "./TopBanner";
<Meta title="UI/TopBanner" component={TopBanner} />
<Title title="TopBanner" suffix="Brief" />
## Definition
Top banner will be position on the very top of the page to communicate on what’s wrong or what’s new.
## Structure
Each toast has a state to represent neutral, positive or negative responses.
<CustomArgsTable of={TopBanner} />
<Examples title="Top Banner Style">
<Example title="Default" isFullWidth={true}>
<TopBanner
actions={
<button
className="border-b border-black text-sm"
onClick={() => {
console.log("test");
}}>
Action
</button>
}
text="Something big is happening we want you to know about."
/>
</Example>
<Example title="Warning" isFullWidth={true}>
<TopBanner
actions={
<button
className="border-b border-black text-sm"
onClick={() => {
console.log("test");
}}>
Action
</button>
}
variant="warning"
text="An app wide warning is occurring that should be resolved."
/>
</Example>
<Example title="Error" isFullWidth={true}>
<TopBanner
actions={
<button
className="border-b border-black text-sm"
onClick={() => {
console.log("test");
}}>
Action
</button>
}
variant="error"
text="A major error is occurring that must be resolved."
/>
</Example>
</Examples>
<Canvas>
<Story
name="TopBanner"
args={{
text: "Something big is happening we want you to know about.",
variant: "default",
}}
argTypes={{
variant: {
control: {
type: "select",
options: ["default", "warning", "error"],
},
},
text: {
control: {
type: "text",
},
},
}}>
{({ text, variant, ...args }) => (
<TopBanner
{...args}
actions={
<button
className="border-b border-black text-sm"
onClick={() => {
alert("test");
}}>
Action
</button>
}
variant={variant}
text={text}
/>
)}
</Story>
</Canvas>
@@ -1,37 +0,0 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { Title, CustomArgsTable, VariantsTable, VariantRow } from "@calcom/storybook/components";
import { UnpublishedEntity } from "./UnpublishedEntity";
<Meta title="UI/UnpublishedEntity" component={UnpublishedEntity} />
<Title title="UnpublishedEntity" suffix="Brief" subtitle="Version 1.0 — Last Update: 17 Aug 2023" />
## Definition
The `UnpublishedEntity` component is used to display an "empty screen" with relevant information for unpublished teams or organizations.
## Structure
The `UnpublishedEntity` component consists of the following parts:
- An `EmptyScreen` component from `@calcom/ui` that displays a visual representation of an "empty screen."
- An `Avatar` component from `@calcom/ui` that shows an avatar image associated with the organization or team.
- Translated text obtained using the `useLocale` hook for displaying messages based on the entity's status.
<CustomArgsTable of={UnpublishedEntity} />
## UnpublishedEntity Story
<Canvas>
<Story name="UnpublishedEntity" args={{ name: "TeamExample", teamSlug: "team-example" }}>
{(args) => (
<VariantsTable titles={["Default"]} columnMinWidth={150}>
<VariantRow>
<UnpublishedEntity {...args} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
-2
View File
@@ -176,8 +176,6 @@ export { HoverCard, HoverCardTrigger, HoverCardContent, HoverCardPortal } from "
export { OrgBanner } from "./components/organization-banner";
export type { OrgBannerProps } from "./components/organization-banner";
export { StorybookTrpcProvider } from "./components/mocks/trpc";
export { NavigationItem } from "./components/navigation/NavigationItem";
export { Pagination } from "./components/pagination";
+1
View File
@@ -100,6 +100,7 @@
"devDependencies": {
"@calcom/config": "*",
"@calcom/tsconfig": "*",
"@testing-library/user-event": "^14.6.1",
"@types/react": "18.0.26",
"@types/react-dom": "^18.0.9",
"execa": "^9.3.0",
+8750 -4424
View File
File diff suppressed because it is too large Load Diff