2
0

first commit

This commit is contained in:
2024-08-09 00:39:27 +02:00
commit 79688abe2e
5698 changed files with 497838 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import type { ReactNode } from "react";
import { classNames } from "@calcom/lib";
import { Label } from "..";
import Switch from "./Switch";
type Props = {
children?: ReactNode;
title: string;
description?: string | React.ReactNode;
checked: boolean;
disabled?: boolean;
LockedIcon?: React.ReactNode;
Badge?: React.ReactNode;
onCheckedChange?: (checked: boolean) => void;
"data-testid"?: string;
tooltip?: string;
toggleSwitchAtTheEnd?: boolean;
childrenClassName?: string;
switchContainerClassName?: string;
labelClassName?: string;
descriptionClassName?: string;
};
function SettingsToggle({
checked,
onCheckedChange,
description,
LockedIcon,
Badge,
title,
children,
disabled,
tooltip,
toggleSwitchAtTheEnd = false,
childrenClassName,
switchContainerClassName,
labelClassName,
descriptionClassName,
...rest
}: Props) {
const [animateRef] = useAutoAnimate<HTMLDivElement>();
return (
<>
<div className="flex w-full flex-col space-y-4 lg:flex-row lg:space-x-4 lg:space-y-0">
<fieldset className="block w-full flex-col sm:flex">
{toggleSwitchAtTheEnd ? (
<div
className={classNames(
"border-subtle flex justify-between space-x-3 rounded-lg border px-4 py-6 sm:px-6",
checked && children && "rounded-b-none",
switchContainerClassName
)}>
<div>
<div className="flex items-center gap-x-2" data-testid={`${rest["data-testid"]}-title`}>
<Label
className={classNames("mt-0.5 text-base font-semibold leading-none", labelClassName)}
htmlFor="">
{title}
{LockedIcon}
</Label>
{Badge && <div className="mb-2">{Badge}</div>}
</div>
{description && (
<p
className={classNames(
"text-default -mt-1.5 text-sm leading-normal",
descriptionClassName
)}
data-testid={`${rest["data-testid"]}-description`}>
{description}
</p>
)}
</div>
<div className="my-auto h-full">
<Switch
data-testid={rest["data-testid"]}
fitToHeight={true}
checked={checked}
onCheckedChange={onCheckedChange}
disabled={disabled}
tooltip={tooltip}
/>
</div>
</div>
) : (
<div className="flex space-x-3">
<Switch
data-testid={rest["data-testid"]}
fitToHeight={true}
checked={checked}
onCheckedChange={onCheckedChange}
disabled={disabled}
tooltip={tooltip}
/>
<div>
<Label
className={classNames("text-emphasis text-sm font-semibold leading-none", labelClassName)}>
{title}
{LockedIcon}
</Label>
{description && <p className="text-default -mt-1.5 text-sm leading-normal">{description}</p>}
</div>
</div>
)}
{children && (
<div className={classNames("lg:ml-14", childrenClassName)} ref={animateRef}>
{checked && <div className={classNames(!toggleSwitchAtTheEnd && "mt-4")}>{children}</div>}
</div>
)}
</fieldset>
</div>
</>
);
}
export default SettingsToggle;

View File

@@ -0,0 +1,82 @@
import { useId } from "@radix-ui/react-id";
import * as Label from "@radix-ui/react-label";
import * as PrimitiveSwitch from "@radix-ui/react-switch";
import type { ReactNode } from "react";
import React from "react";
import cx from "@calcom/lib/classNames";
import { Tooltip } from "../../tooltip";
const Wrapper = ({ children, tooltip }: { tooltip?: string; children: React.ReactNode }) => {
if (!tooltip) {
return <>{children}</>;
}
return <Tooltip content={tooltip}>{children}</Tooltip>;
};
const Switch = (
props: React.ComponentProps<typeof PrimitiveSwitch.Root> & {
label?: string | ReactNode;
fitToHeight?: boolean;
disabled?: boolean;
tooltip?: string;
small?: boolean;
labelOnLeading?: boolean;
classNames?: {
container?: string;
thumb?: string;
};
LockedIcon?: React.ReactNode;
}
) => {
const { label, fitToHeight, classNames, small, labelOnLeading, LockedIcon, ...primitiveProps } = props;
const id = useId();
const isChecked = props.checked || props.defaultChecked;
return (
<Wrapper tooltip={props.tooltip}>
<div
className={cx(
"flex h-auto w-auto flex-row items-center",
fitToHeight && "h-fit",
labelOnLeading && "flex-row-reverse",
classNames?.container
)}>
{LockedIcon && <div className="mr-2">{LockedIcon}</div>}
<PrimitiveSwitch.Root
className={cx(
isChecked ? "bg-brand-default dark:bg-brand-emphasis" : "bg-emphasis",
primitiveProps.disabled && "cursor-not-allowed",
small ? "h-4 w-[27px]" : "h-5 w-[34px]",
"focus:ring-brand-default rounded-full shadow-none transition focus:border-neutral-300 focus:outline-none focus:ring-2 focus:ring-neutral-800 focus:ring-offset-1",
props.className
)}
{...primitiveProps}>
<PrimitiveSwitch.Thumb
id={id}
className={cx(
small
? "h-[10px] w-[10px] ltr:translate-x-[2px] rtl:-translate-x-[2px] ltr:[&[data-state='checked']]:translate-x-[13px] rtl:[&[data-state='checked']]:-translate-x-[13px]"
: "h-[14px] w-[14px] ltr:translate-x-[4px] rtl:-translate-x-[4px] ltr:[&[data-state='checked']]:translate-x-[17px] rtl:[&[data-state='checked']]:-translate-x-[17px]",
"block rounded-full transition will-change-transform",
isChecked ? "bg-brand-accent shadow-inner" : "bg-default",
classNames?.thumb
)}
/>
</PrimitiveSwitch.Root>
{label && (
<Label.Root
htmlFor={id}
className={cx(
"text-emphasis ms-2 align-text-top text-sm font-medium",
primitiveProps.disabled ? "cursor-not-allowed opacity-25" : "cursor-pointer",
labelOnLeading && "flex-1"
)}>
{label}
</Label.Root>
)}
</div>
</Wrapper>
);
};
export default Switch;

View File

@@ -0,0 +1,2 @@
export { default as SettingsToggle } from "./SettingsToggle";
export { default as Switch } from "./Switch";

View File

@@ -0,0 +1,97 @@
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>