NODEDC_TASKMANAGER/plane-src/packages/propel/src/switch/switch.stories.tsx

248 lines
7.8 KiB
TypeScript

/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { useArgs } from "storybook/preview-api";
import { Switch } from "./root";
const meta = {
title: "Components/Switch",
component: Switch,
parameters: {
layout: "centered",
},
tags: ["autodocs"],
args: { value: false, onChange: () => {} },
render(args) {
const [{ value }, updateArgs] = useArgs();
const setValue = (newValue: boolean) => updateArgs({ value: newValue });
return <Switch {...args} value={value} onChange={setValue} />;
},
} satisfies Meta<typeof Switch>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {};
export const Checked: Story = {
args: { value: true },
};
export const WithLabel: Story = {
render(args) {
const [value, setValue] = useState(args.value);
return (
<div className="flex items-center gap-2">
<Switch {...args} value={value} onChange={setValue} label="Enable notifications" />
<label className="text-13">Enable notifications</label>
</div>
);
},
};
export const Small: Story = {
args: { size: "sm" },
};
export const Medium: Story = {
args: { size: "md" },
};
export const Large: Story = {
args: { size: "lg" },
};
export const Disabled: Story = {
args: { disabled: true },
};
export const DisabledChecked: Story = {
args: { value: true, disabled: true },
};
export const AllSizes: Story = {
render() {
const [small, setSmall] = useState(false);
const [medium, setMedium] = useState(false);
const [large, setLarge] = useState(false);
return (
<div className="flex items-center gap-6">
<div className="text-center">
<Switch value={small} onChange={setSmall} size="sm" />
<p className="text-gray-600 mt-2 text-11">Small</p>
</div>
<div className="text-center">
<Switch value={medium} onChange={setMedium} size="md" />
<p className="text-gray-600 mt-2 text-11">Medium</p>
</div>
<div className="text-center">
<Switch value={large} onChange={setLarge} size="lg" />
<p className="text-gray-600 mt-2 text-11">Large</p>
</div>
</div>
);
},
};
export const AllStates: Story = {
render() {
const [unchecked, setUnchecked] = useState(false);
const [checked, setChecked] = useState(true);
const [disabledUnchecked] = useState(false);
const [disabledChecked] = useState(true);
return (
<div className="space-y-4">
<div className="flex items-center gap-4">
<Switch value={unchecked} onChange={setUnchecked} />
<span className="text-gray-600 text-13">Unchecked</span>
</div>
<div className="flex items-center gap-4">
<Switch value={checked} onChange={setChecked} />
<span className="text-gray-600 text-13">Checked</span>
</div>
<div className="flex items-center gap-4">
<Switch value={disabledUnchecked} onChange={() => {}} disabled />
<span className="text-gray-600 text-13">Disabled Unchecked</span>
</div>
<div className="flex items-center gap-4">
<Switch value={disabledChecked} onChange={() => {}} disabled />
<span className="text-gray-600 text-13">Disabled Checked</span>
</div>
</div>
);
},
};
export const InForm: Story = {
render() {
const [notifications, setNotifications] = useState(true);
const [marketing, setMarketing] = useState(false);
const [updates, setUpdates] = useState(true);
return (
<div className="border-gray-200 shadow-md w-80 rounded-lg border bg-white p-6">
<h3 className="text-16 font-semibold">Notification Settings</h3>
<div className="mt-4 space-y-4">
<div className="flex items-center justify-between">
<div>
<p className="text-13 font-medium">Push Notifications</p>
<p className="text-gray-500 text-11">Receive push notifications on your device</p>
</div>
<Switch value={notifications} onChange={setNotifications} size="md" />
</div>
<div className="flex items-center justify-between">
<div>
<p className="text-13 font-medium">Marketing Emails</p>
<p className="text-gray-500 text-11">Receive emails about new features</p>
</div>
<Switch value={marketing} onChange={setMarketing} size="md" />
</div>
<div className="flex items-center justify-between">
<div>
<p className="text-13 font-medium">Product Updates</p>
<p className="text-gray-500 text-11">Get notified about product updates</p>
</div>
<Switch value={updates} onChange={setUpdates} size="md" />
</div>
</div>
</div>
);
},
};
export const WithDescription: Story = {
render() {
const [enabled, setEnabled] = useState(false);
return (
<div className="border-gray-200 w-96 rounded-lg border bg-white p-6">
<div className="flex items-start justify-between">
<div className="flex-1">
<h4 className="text-13 font-semibold">Enable Two-Factor Authentication</h4>
<p className="text-gray-500 mt-1 text-11">
Add an extra layer of security to your account by enabling two-factor authentication.
</p>
</div>
<Switch value={enabled} onChange={setEnabled} size="md" className="ml-4" />
</div>
</div>
);
},
};
export const Interactive: Story = {
render() {
const [enabled, setEnabled] = useState(false);
return (
<div className="border-gray-200 w-80 space-y-4 rounded-lg border bg-white p-6">
<div className="flex items-center justify-between">
<span className="text-13 font-medium">Feature Toggle</span>
<Switch value={enabled} onChange={setEnabled} size="md" />
</div>
<div className="bg-gray-50 rounded-sm p-4">
<p className="text-gray-700 text-13">
Status: <span className="font-semibold">{enabled ? "Enabled" : "Disabled"}</span>
</p>
{enabled && <p className="mt-2 text-11 text-success-primary">Feature is now active and ready to use!</p>}
</div>
</div>
);
},
};
export const CustomStyles: Story = {
render() {
const [value, setValue] = useState(false);
return (
<div className="flex items-center gap-4">
<Switch
value={value}
onChange={setValue}
size="lg"
className="border-purple-300 data-[state=checked]:bg-purple-500 border-2"
/>
<span className="text-13">Custom styled switch</span>
</div>
);
},
};
export const MultipleControls: Story = {
render() {
const [settings, setSettings] = useState({
feature1: true,
feature2: false,
feature3: true,
feature4: false,
feature5: true,
});
const toggleSetting = (key: keyof typeof settings) => {
setSettings((prev) => ({ ...prev, [key]: !prev[key] }));
};
return (
<div className="border-gray-200 w-96 rounded-lg border bg-white p-6">
<h3 className="mb-4 text-16 font-semibold">Feature Flags</h3>
<div className="space-y-3">
{Object.entries(settings).map(([key, value]) => (
<div key={key} className="flex items-center justify-between">
<span className="text-13 capitalize">{key.replace(/([A-Z])/g, " $1").trim()}</span>
<Switch value={value} onChange={() => toggleSetting(key as keyof typeof settings)} size="sm" />
</div>
))}
</div>
</div>
);
},
};