ui(component): Added new Toast (Sonner) component (#4412)
This commit is contained in:
1 parent
43f54aa49c
commit
e0fca8c88c
16 files changed
+1212
-247
No files matched your search
@@ -176,12 +176,14 @@ module.exports = {
|
||||
target: '_blank',
|
||||
position: 'left',
|
||||
},
|
||||
/*
|
||||
{
|
||||
to: '/playground',
|
||||
label: 'UI Playground',
|
||||
position: 'left',
|
||||
className: 'new-badge',
|
||||
},
|
||||
*/
|
||||
{
|
||||
to: '/help',
|
||||
//activeBaseRegex: '(^/help$)|(/help)',
|
||||
|
||||
@@ -10,16 +10,22 @@ export default function Patterns() {
|
||||
<h1>Patterns</h1>
|
||||
<button
|
||||
className="bg-slate-400"
|
||||
onClick={() => history.push('/patterns/segmentation-panel')}
|
||||
onClick={() => history.push('/patterns/patterns-segmentation')}
|
||||
>
|
||||
{'Segmentation Panel'}
|
||||
</button>
|
||||
<button
|
||||
className="bg-slate-400"
|
||||
onClick={() => history.push('/patterns/measurement-panel')}
|
||||
onClick={() => history.push('/patterns/patterns-measurements')}
|
||||
>
|
||||
{'Measurements Panel'}
|
||||
</button>
|
||||
<button
|
||||
className="bg-slate-400"
|
||||
onClick={() => history.push('/patterns/patterns-tmtv')}
|
||||
>
|
||||
{'tmtv'}
|
||||
</button>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
File renamed without changes.
+56
@@ -10,6 +10,18 @@ import {
|
||||
SelectItem,
|
||||
} from '../../../../ui-next/src/components/Select';
|
||||
import { Icons } from '../../../../ui-next/src/components/Icons';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuPortal,
|
||||
} from '../../../../ui-next/src/components/DropdownMenu';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionItem,
|
||||
@@ -85,6 +97,50 @@ export default function SegmentationPanel() {
|
||||
<div className="mb-0">
|
||||
{/* Header Controls */}
|
||||
<div className="bg-muted flex h-10 w-full items-center space-x-1 rounded-t px-1.5">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
>
|
||||
<Icons.More className="h-6 w-6" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>
|
||||
<Icons.Add className="text-foreground" />
|
||||
<span className="pl-2">Create New Segmentation</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuLabel>Manage Current Segmentation</DropdownMenuLabel>
|
||||
<DropdownMenuItem>
|
||||
<Icons.Series className="text-foreground" />
|
||||
<span className="pl-2">Remove from Viewport</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Icons.Rename className="text-foreground" />
|
||||
<span className="pl-2">Rename</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger>
|
||||
<Icons.Export className="text-foreground" />
|
||||
<span className="pl-2">Export & Download</span>
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuSubContent>
|
||||
<DropdownMenuItem>Export DICOM SEG</DropdownMenuItem>
|
||||
<DropdownMenuItem>Download DICOM SEG</DropdownMenuItem>
|
||||
<DropdownMenuItem>Download DICOM RTSTRUCT</DropdownMenuItem>
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuSub>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<Icons.Delete className="text-red-600" />
|
||||
<span className="pl-2 text-red-600">Delete</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Select>
|
||||
<SelectTrigger className="w-full overflow-hidden">
|
||||
<SelectValue placeholder="Segmentation 1" />
|
||||
@@ -0,0 +1,43 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { DataRow } from '../../../../ui-next/src/components/DataRow';
|
||||
import { Button } from '../../../../ui-next/src/components/Button';
|
||||
import {
|
||||
Select,
|
||||
SelectValue,
|
||||
SelectTrigger,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
} from '../../../../ui-next/src/components/Select';
|
||||
import { Icons } from '../../../../ui-next/src/components/Icons';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
AccordionContent,
|
||||
} from '../../../../ui-next/src/components/Accordion';
|
||||
import { Slider } from '../../../../ui-next/src/components/Slider';
|
||||
import { Switch } from '../../../../ui-next/src/components/Switch';
|
||||
import { Label } from '../../../../ui-next/src/components/Label';
|
||||
import { Input } from '../../../../ui-next/src/components/Input';
|
||||
import { Tabs, TabsList, TabsTrigger } from '../../../../ui-next/src/components/Tabs';
|
||||
import { actionOptionsMap, dataList } from '../../../../ui-next/assets/data';
|
||||
|
||||
interface DataItem {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
optionalField?: string;
|
||||
colorHex?: string;
|
||||
details?: string;
|
||||
series?: string;
|
||||
}
|
||||
|
||||
interface ListGroup {
|
||||
type: string;
|
||||
items: DataItem[];
|
||||
}
|
||||
|
||||
export default function SplitPanel() {
|
||||
return <div>hellosssssss</div>;
|
||||
}
|
||||
@@ -0,0 +1,403 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { Button } from '../../../../ui-next/src/components/Button';
|
||||
import {
|
||||
Select,
|
||||
SelectGroup,
|
||||
SelectValue,
|
||||
SelectTrigger,
|
||||
SelectContent,
|
||||
SelectLabel,
|
||||
SelectItem,
|
||||
SelectSeparator,
|
||||
SelectScrollUpButton,
|
||||
SelectScrollDownButton,
|
||||
} from '../../../../ui-next/src/components/Select';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSub,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuPortal,
|
||||
} from '../../../../ui-next/src/components/DropdownMenu';
|
||||
import { Icons } from '../../../../ui-next/src/components/Icons/Icons';
|
||||
import { DataRow } from '../../../../ui-next/src/components/DataRow';
|
||||
import { actionOptionsMap, dataList } from '../../../../ui-next/assets/data';
|
||||
|
||||
import {
|
||||
Accordion,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
AccordionContent,
|
||||
} from '../../../../ui-next/src/components/Accordion/Accordion';
|
||||
import { Slider } from '../../../../ui-next/src/components/Slider';
|
||||
import { Switch } from '../../../../ui-next/src/components/Switch';
|
||||
import { Label } from '../../../../ui-next/src/components/Label';
|
||||
import { Input } from '../../../../ui-next/src/components/Input';
|
||||
import { Tabs, TabsList, TabsTrigger, TabsContent } from '../../../../ui-next/src/components/Tabs';
|
||||
|
||||
import { ChevronDownIcon } from '@radix-ui/react-icons';
|
||||
|
||||
interface DataItem {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
optionalField?: string;
|
||||
colorHex?: string;
|
||||
details?: string;
|
||||
series?: string;
|
||||
}
|
||||
|
||||
interface ListGroup {
|
||||
type: string;
|
||||
items: DataItem[];
|
||||
}
|
||||
|
||||
export default function TMTVPatterns() {
|
||||
const [selectedRowId, setSelectedRowId] = useState<string | null>(null);
|
||||
const [selectedTab, setSelectedTab] = useState<string>('Fill & Outline');
|
||||
|
||||
const handleAction = (id: string, action: string) => {
|
||||
console.log(`Action "${action}" triggered for item with id: ${id}`);
|
||||
// Implement actual action logic here
|
||||
};
|
||||
|
||||
// Handle row selection
|
||||
const handleRowSelect = (id: string) => {
|
||||
setSelectedRowId(prevSelectedId => (prevSelectedId === id ? null : id));
|
||||
};
|
||||
|
||||
// Find the "TMTV2" group
|
||||
const tmv2Group = dataList.find((listGroup: ListGroup) => listGroup.type === 'TMTV2');
|
||||
|
||||
// Find the "TMTV1" group
|
||||
const tmvGroup = dataList.find((listGroup: ListGroup) => listGroup.type === 'TMTV1');
|
||||
|
||||
// Check if both groups exist
|
||||
if (!tmv2Group) {
|
||||
return <div className="text-red-500">TMTV2 data not found.</div>;
|
||||
}
|
||||
|
||||
if (!tmvGroup) {
|
||||
return <div className="text-red-500">TMTV1 data not found.</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="px-auto my-4 flex h-full w-full justify-center bg-black py-6">
|
||||
<div className="w-64 space-y-0">
|
||||
<Accordion
|
||||
type="multiple"
|
||||
defaultValue={['segmentation-tools', 'segmentation-list', 'tmv1-group', 'tmv2-group']}
|
||||
collapsible
|
||||
>
|
||||
{/* Segmentation Tools */}
|
||||
<AccordionItem value="segmentation-tools">
|
||||
<AccordionTrigger className="bg-popover hover:bg-accent text-muted-foreground my-0.5 flex h-7 w-full items-center justify-between rounded py-2 pr-1 pl-2 font-normal">
|
||||
<span>Segmentation Tools</span>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="bg-muted mb-0.5 h-32 rounded-b pb-3"></div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
{/* Segmentation List */}
|
||||
<AccordionItem value="segmentation-list">
|
||||
<AccordionTrigger className="bg-popover hover:bg-accent text-muted-foreground my-0.5 flex h-7 w-full items-center justify-between rounded py-2 pr-1 pl-2 font-normal">
|
||||
<span>Segmentation List</span>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
{/* Appearance Settings */}
|
||||
<AccordionItem value="segmentation-display">
|
||||
<AccordionTrigger className="bg-muted hover:bg-accent mt-0.5 flex h-7 w-full items-center justify-between rounded-b pr-1 pl-2 font-normal text-white">
|
||||
<div className="flex space-x-2">
|
||||
<Icons.Controls className="text-primary" />
|
||||
<span className="text-primary pr-1">Appearance Settings</span>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
<div className="bg-muted mb-0.5 space-y-2 rounded-b px-px pt-0.5 pb-3">
|
||||
<div className="mx-1 mb-2.5 mt-1 flex items-center justify-between space-x-4">
|
||||
{/* Display Label with Selected Tab */}
|
||||
<div className="text-muted-foreground text-xs">Show: {selectedTab}</div>
|
||||
{/* Tabs Controls */}
|
||||
<Tabs
|
||||
value={selectedTab}
|
||||
onValueChange={setSelectedTab}
|
||||
>
|
||||
<TabsList>
|
||||
<TabsTrigger value="Fill & Outline">
|
||||
<Icons.DisplayFillAndOutline className="text-primary" />
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="Outline Only">
|
||||
<Icons.DisplayOutlineOnly className="text-primary" />
|
||||
</TabsTrigger>
|
||||
<TabsTrigger value="Fill Only">
|
||||
<Icons.DisplayFillOnly className="text-primary" />
|
||||
</TabsTrigger>
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
</div>
|
||||
{/* Opacity Slider */}
|
||||
<div className="my-2 flex items-center ">
|
||||
<Label className="text-muted-foreground mx-1 w-14 flex-none whitespace-nowrap text-xs">
|
||||
Opacity
|
||||
</Label>
|
||||
<Slider
|
||||
className="mx-1 flex-1"
|
||||
defaultValue={[85]}
|
||||
max={100}
|
||||
step={1}
|
||||
/>
|
||||
<Input
|
||||
className="mx-1 w-10 flex-none"
|
||||
placeholder="85"
|
||||
/>
|
||||
</div>
|
||||
{/* Border Slider */}
|
||||
<div className="my-2 flex items-center">
|
||||
<Label className="text-muted-foreground mx-1 w-14 flex-none whitespace-nowrap text-xs">
|
||||
Border
|
||||
</Label>
|
||||
<Slider
|
||||
className="mx-1 flex-1"
|
||||
defaultValue={[10]}
|
||||
max={100}
|
||||
step={1}
|
||||
/>
|
||||
<Input
|
||||
className="mx-1 w-10 flex-none"
|
||||
placeholder="2"
|
||||
/>
|
||||
</div>
|
||||
{/* Sync Changes Switch */}
|
||||
<div className="my-2 flex items-center pl-1 pb-1">
|
||||
<Switch defaultChecked />
|
||||
<Label className="text-muted-foreground mx-2 w-14 flex-none whitespace-nowrap text-xs">
|
||||
Sync changes in all viewports
|
||||
</Label>
|
||||
</div>
|
||||
<div className="border-input w-full border"></div>
|
||||
{/* Display Inactive Segmentations Switch */}
|
||||
<div className="my-2 flex items-center pl-1">
|
||||
<Switch defaultChecked />
|
||||
<Label className="text-muted-foreground mx-2 w-14 flex-none whitespace-nowrap text-xs">
|
||||
Display inactive segmentations
|
||||
</Label>
|
||||
</div>
|
||||
{/* Additional Opacity Slider */}
|
||||
<div className="my-2 flex items-center ">
|
||||
<Label className="text-muted-foreground mx-1 w-14 flex-none whitespace-nowrap text-xs">
|
||||
Opacity
|
||||
</Label>
|
||||
<Slider
|
||||
className="mx-1 flex-1"
|
||||
defaultValue={[65]}
|
||||
max={100}
|
||||
step={1}
|
||||
/>
|
||||
<Input
|
||||
className="mx-1 w-10 flex-none"
|
||||
placeholder="65"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
{/* TMTV1 Group */}
|
||||
<AccordionItem value="tmv1-group">
|
||||
<AccordionTrigger className="hover:bg-popover mr-0 flex h-8 w-full items-center pl-0 pr-1">
|
||||
<div className="text-foreground border-input flex h-8 w-full items-center justify-between border-t-2">
|
||||
{/* Left Group: DropdownMenu and TMTV1 Label */}
|
||||
<div className="flex items-center space-x-1">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="ml-1"
|
||||
>
|
||||
<Icons.More className="h-6 w-6" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>
|
||||
<Icons.Add className="text-foreground" />
|
||||
<span className="pl-2">Add Segment</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<Icons.Series className="text-foreground" />
|
||||
<span className="pl-2">Remove from Viewport</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Icons.Rename className="text-foreground" />
|
||||
<span className="pl-2">Rename</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Icons.Hide className="text-foreground" />
|
||||
<span className="pl-2">Hide or Show all Segments</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger>
|
||||
<Icons.Export className="text-foreground" />
|
||||
<span className="pl-2">Export & Download</span>
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuSubContent>
|
||||
<DropdownMenuItem>Export DICOM SEG</DropdownMenuItem>
|
||||
<DropdownMenuItem>Download DICOM SEG</DropdownMenuItem>
|
||||
<DropdownMenuItem>Download DICOM RTSTRUCT</DropdownMenuItem>
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuSub>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<Icons.Delete className="text-red-600" />
|
||||
<span className="pl-2 text-red-600">Delete</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<div className="pl-1.5">TMTV1 Segmentation</div>
|
||||
</div>
|
||||
<div className="mr-1 flex items-center">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
>
|
||||
<Icons.Info className="h-6 w-6" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
{/* Data Rows for TMTV1 */}
|
||||
<div className="space-y-px">
|
||||
{tmvGroup.items.map((item, index) => {
|
||||
const compositeId = `${tmvGroup.type}-${item.id}-panel`; // Ensure unique composite ID
|
||||
return (
|
||||
<DataRow
|
||||
key={`panel-${compositeId}`} // Prefix to ensure uniqueness
|
||||
number={index + 1}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
optionalField={item.optionalField}
|
||||
colorHex={item.colorHex}
|
||||
details={item.details}
|
||||
series={item.series}
|
||||
actionOptions={actionOptionsMap[tmvGroup.type] || ['Action']}
|
||||
onAction={(action: string) => handleAction(compositeId, action)}
|
||||
isSelected={selectedRowId === compositeId}
|
||||
onSelect={() => handleRowSelect(compositeId)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
{/* TMTV2 Group */}
|
||||
<AccordionItem value="tmv2-group">
|
||||
<AccordionTrigger className="hover:bg-popover mr-0 flex h-8 w-full items-center pl-0 pr-1">
|
||||
<div className="text-foreground border-input flex h-8 w-full items-center justify-between border-t-2">
|
||||
<div className="flex items-center space-x-1">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="ml-1"
|
||||
>
|
||||
<Icons.More className="h-6 w-6" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>
|
||||
<Icons.Add className="text-foreground" />
|
||||
<span className="pl-2">Add Segment</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<Icons.Series className="text-foreground" />
|
||||
<span className="pl-2">Remove from Viewport</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Icons.Rename className="text-foreground" />
|
||||
<span className="pl-2">Rename</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Icons.Hide className="text-foreground" />
|
||||
<span className="pl-2">Hide or Show all Segments</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSub>
|
||||
<DropdownMenuSubTrigger>
|
||||
<Icons.Export className="text-foreground" />
|
||||
<span className="pl-2">Export & Download</span>
|
||||
</DropdownMenuSubTrigger>
|
||||
<DropdownMenuPortal>
|
||||
<DropdownMenuSubContent>
|
||||
<DropdownMenuItem>Export DICOM SEG</DropdownMenuItem>
|
||||
<DropdownMenuItem>Download DICOM SEG</DropdownMenuItem>
|
||||
<DropdownMenuItem>Download DICOM RTSTRUCT</DropdownMenuItem>
|
||||
</DropdownMenuSubContent>
|
||||
</DropdownMenuPortal>
|
||||
</DropdownMenuSub>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem>
|
||||
<Icons.Delete className="text-red-600" />
|
||||
<span className="pl-2 text-red-600">Delete</span>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
<div className="pl-1.5">TMTV2 Segmentation</div>
|
||||
</div>
|
||||
<div className="mr-1 flex items-center ">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
>
|
||||
<Icons.Info className="h-6 w-6" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
{/* Data Rows for TMTV2 */}
|
||||
<div className="space-y-px">
|
||||
{tmv2Group.items.map((item, index) => {
|
||||
const compositeId = `${tmv2Group.type}-${item.id}-panel`; // Ensure unique composite ID
|
||||
return (
|
||||
<DataRow
|
||||
key={`panel-${compositeId}`} // Prefix to ensure uniqueness
|
||||
number={index + 1}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
optionalField={item.optionalField}
|
||||
colorHex={item.colorHex}
|
||||
details={item.details}
|
||||
series={item.series}
|
||||
actionOptions={actionOptionsMap[tmv2Group.type] || ['Action']}
|
||||
onAction={(action: string) => handleAction(compositeId, action)}
|
||||
isSelected={selectedRowId === compositeId}
|
||||
onSelect={() => handleRowSelect(compositeId)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
{/* Footer or Additional Information */}
|
||||
<div className="bg-popover text-foreground flex h-8 items-center justify-between pl-9 pr-3 text-sm font-semibold">
|
||||
<span>TMTV</span>
|
||||
<span>21.555 mL</span>
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
DropdownMenuItem,
|
||||
} from '../../../ui-next/src/components/DropdownMenu';
|
||||
import { Icons } from '../../../ui-next/src/components/Icons';
|
||||
import { Toaster, toast } from '../../../ui-next/src/components/Sonner';
|
||||
|
||||
interface ShowcaseRowProps {
|
||||
title: string;
|
||||
@@ -34,6 +35,106 @@ interface ShowcaseRowProps {
|
||||
}
|
||||
|
||||
export default function ComponentShowcase() {
|
||||
// Handlers to trigger different types of toasts
|
||||
const triggerSuccess = () => {
|
||||
toast.success('This is a success toast!');
|
||||
};
|
||||
|
||||
const triggerError = () => {
|
||||
toast.error('This is an error toast!');
|
||||
};
|
||||
|
||||
const triggerInfo = () => {
|
||||
toast.info('This is an info toast!');
|
||||
};
|
||||
|
||||
const triggerWarning = () => {
|
||||
toast.warning('This is a warning toast!');
|
||||
};
|
||||
|
||||
// Handler to trigger a toast.promise example
|
||||
const triggerPromiseToast = () => {
|
||||
const promise = () =>
|
||||
new Promise<{ name: string }>(resolve =>
|
||||
setTimeout(() => resolve({ name: 'Segmentation 1' }), 3000)
|
||||
);
|
||||
|
||||
toast.promise(promise(), {
|
||||
loading: 'Loading Segmentation...',
|
||||
success: data => `${data.name} has been added`,
|
||||
error: 'Error',
|
||||
});
|
||||
};
|
||||
|
||||
// Handler to trigger a toast with description
|
||||
const triggerDescriptionToast = () => {
|
||||
toast.success('Success heading', {
|
||||
description: 'This is a detailed description of the success message.',
|
||||
});
|
||||
};
|
||||
|
||||
// Handler to trigger a toast with an action button
|
||||
const triggerActionButtonToast = () => {
|
||||
toast.info('Info heading', {
|
||||
description: 'This is an info message with an action button.',
|
||||
action: (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => alert('Action button clicked')}
|
||||
>
|
||||
Undo
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
// Handler to trigger a toast with a cancel button
|
||||
const triggerCancelButtonToast = () => {
|
||||
toast.error('Error!', {
|
||||
description: 'This is an error message with a cancel button.',
|
||||
cancel: (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => toast.dismiss()}
|
||||
>
|
||||
Dismiss
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
// Handler to trigger a toast with both action and cancel buttons
|
||||
const triggerCombinedToast = () => {
|
||||
toast.warning('Warning!', {
|
||||
description: 'This is a warning with both action and cancel buttons.',
|
||||
action: (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => alert('Retry action clicked')}
|
||||
>
|
||||
Retry
|
||||
</Button>
|
||||
),
|
||||
cancel: (
|
||||
<Button
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
onClick={() => toast.dismiss()}
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
// Handler to trigger a loading toast using Toaster's default loading icon
|
||||
const showLoadingToast = () => {
|
||||
toast.loading('Loading your data...');
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-background text-foreground h-full">
|
||||
<div className="mx-auto my-4 max-w-6xl py-6">
|
||||
@@ -488,6 +589,82 @@ export default function ComponentShowcase() {
|
||||
do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
</ScrollArea>
|
||||
</ShowcaseRow>
|
||||
<ShowcaseRow
|
||||
title="sonner 1"
|
||||
description="sonner1"
|
||||
code={`sdf`}
|
||||
>
|
||||
{/* Toast Examples Section */}
|
||||
<div className="space-x-2">
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerSuccess}
|
||||
>
|
||||
Show Success Toast
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerError}
|
||||
>
|
||||
Show Error Toast
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerInfo}
|
||||
>
|
||||
Show Info Toast
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerWarning}
|
||||
>
|
||||
Show Warning Toast
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerPromiseToast}
|
||||
>
|
||||
Loading & Success Toast
|
||||
</Button>
|
||||
</div>
|
||||
</ShowcaseRow>
|
||||
|
||||
<ShowcaseRow
|
||||
title="sonner 2"
|
||||
description="sonner2"
|
||||
code={`sdf`}
|
||||
>
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerDescriptionToast}
|
||||
>
|
||||
Show Toast with Description
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerActionButtonToast}
|
||||
>
|
||||
Show Toast with Action Button
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerCancelButtonToast}
|
||||
>
|
||||
Show Toast with Cancel Button
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="default"
|
||||
onClick={triggerCombinedToast}
|
||||
>
|
||||
Show Toast with Action & Cancel Buttons
|
||||
</Button>
|
||||
|
||||
{/* Render the Toaster component */}
|
||||
<Toaster />
|
||||
</ShowcaseRow>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -205,6 +205,58 @@ const dataList = [
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'TMTV1',
|
||||
items: [
|
||||
{
|
||||
id: 29,
|
||||
title: 'Segment 1',
|
||||
colorHex: '#FF6F61',
|
||||
description: 'Description for Segmentation One.',
|
||||
details: 'SUV Peak: NaN\nVolume: 21.56mm³',
|
||||
},
|
||||
{
|
||||
id: 30,
|
||||
title: 'Segment 2',
|
||||
colorHex: '#00CED1',
|
||||
description: 'Description for Segmentation Two.',
|
||||
details: 'SUV Peak: NaN\nVolume: 21.56mm³',
|
||||
},
|
||||
{
|
||||
id: 31,
|
||||
title: 'Segment 3',
|
||||
colorHex: '#88B04B',
|
||||
description: 'Description for Segmentation One.',
|
||||
details: 'SUV Peak: NaN\nVolume: 21.56mm³',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'TMTV2',
|
||||
items: [
|
||||
{
|
||||
id: 32,
|
||||
title: 'Segment A',
|
||||
colorHex: '#FF6F61',
|
||||
description: 'Description for Segmentation One.',
|
||||
details: 'SUV Peak: NaN\nVolume: 21.56mm³',
|
||||
},
|
||||
{
|
||||
id: 33,
|
||||
title: 'Segment B',
|
||||
colorHex: '#00CED1',
|
||||
description: 'Description for Segmentation Two.',
|
||||
details: 'SUV Peak: NaN\nVolume: 21.56mm³',
|
||||
},
|
||||
{
|
||||
id: 34,
|
||||
title: 'Segment C',
|
||||
colorHex: '#88B04B',
|
||||
description: 'Description for Segmentation One.',
|
||||
details: 'SUV Peak: NaN\nVolume: 21.56mm³',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export { actionOptionsMap, dataList };
|
||||
@@ -54,7 +54,7 @@
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-shepherd": "6.1.1",
|
||||
"shepherd.js": "13.0.3",
|
||||
"sonner": "^1.4.41",
|
||||
"sonner": "^1.5.0",
|
||||
"tailwind-merge": "^2.3.0",
|
||||
"tailwindcss": "3.2.4",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
|
||||
@@ -169,6 +169,10 @@ const DataRow: React.FC<DataRowProps> = ({
|
||||
<Icons.Lock className="text-foreground" />
|
||||
<span className="pl-2">Lock</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Icons.ColorChange className="text-foreground" />
|
||||
<span className="pl-2">Change Color</span>
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem>
|
||||
<Icons.Delete className="text-foreground" />
|
||||
<span className="pl-2">Delete</span>
|
||||
|
||||
@@ -122,6 +122,101 @@ export const Icons = {
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
ColorChange: (props: IconProps) => (
|
||||
<svg
|
||||
width="24px"
|
||||
height="24px"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<g
|
||||
id="ColorChange"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
>
|
||||
<rect
|
||||
id="Rectangle"
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
></rect>
|
||||
<g
|
||||
id="Group-4"
|
||||
transform="translate(4, 5)"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M11.9830989,1.93861826 C10.5789104,0.665654409 8.7439168,-0.0269214719 6.84881419,0.000801239617 C3.06621664,0.000801239617 0,2.55531723 0,5.70792489 C0.13353775,8.17267636 1.81407658,10.2821527 4.18664171,10.963157 C5.1582084,11.3047338 5.96098033,11.0256244 6.52318651,9.75767005 C6.72995019,9.15827585 7.22615951,8.70434675 7.84154981,8.55163978 C8.45694011,8.39893281 9.10779864,8.568221 9.57079585,9.00141636 L9.70370511,9.13432562"
|
||||
id="Path"
|
||||
></path>
|
||||
<line
|
||||
x1="13.2723188"
|
||||
y1="6.75657895"
|
||||
x2="9.69838874"
|
||||
y2="13.9017808"
|
||||
id="Path"
|
||||
></line>
|
||||
<path
|
||||
d="M12.5054323,4.46389421 C12.1415749,5.29815229 12.4941364,6.27127189 13.3079188,6.67887077 C14.1217013,7.08646964 15.1121527,6.7860243 15.5623453,5.99500889 C16.4969889,4.55848545 16.3097611,2.6657723 15.1117829,1.44020853 C15.0640204,1.39470251 14.9942555,1.38091172 14.9327711,1.40482233 C14.8712867,1.42873293 14.8291685,1.48603381 14.8246989,1.55185231 C14.8366608,3.08695427 13.4517463,2.56727906 12.5054323,4.46389421 Z"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M3.52608268,6.59044238 C3.70959208,6.59044238 3.85835583,6.73920613 3.85835583,6.92271553"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M3.19380953,6.92404462 C3.19345611,6.83569024 3.22830728,6.75083342 3.29065893,6.68823236 C3.35301058,6.62563131 3.4377276,6.59044167 3.52608268,6.59044238"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M3.52608268,7.25498868 C3.34257329,7.25498868 3.19380953,7.10622492 3.19380953,6.92271553"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M3.85835583,6.92404462 C3.85762387,7.10703476 3.70907428,7.25499014 3.52608268,7.25498868"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M4.52290214,3.26771086 C4.70641153,3.26771086 4.85517529,3.41647462 4.85517529,3.59998401"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M4.19062898,3.60131311 C4.19062898,3.41780371 4.33939274,3.26903996 4.52290214,3.26903996"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M4.52290214,3.93225717 C4.33939274,3.93225717 4.19062898,3.78349341 4.19062898,3.59998401"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M4.85517529,3.60131311 C4.85444332,3.78430325 4.70589374,3.93225863 4.52290214,3.93225717"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M7.84563365,2.60316456 C8.02914304,2.60316456 8.1779068,2.75192832 8.1779068,2.93543771"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M7.5133605,2.9367668 C7.51300708,2.84841243 7.54785824,2.76355561 7.61020989,2.70095455 C7.67256154,2.63835349 7.75727857,2.60316385 7.84563365,2.60316456"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M7.84563365,3.26771086 C7.66212425,3.26771086 7.5133605,3.11894711 7.5133605,2.93543771"
|
||||
id="Path"
|
||||
></path>
|
||||
<path
|
||||
d="M8.1779068,2.9367668 C8.1779068,3.1202762 8.02914304,3.26903996 7.84563365,3.26903996"
|
||||
id="Path"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
Controls: (props: IconProps) => (
|
||||
<svg
|
||||
width="18px"
|
||||
@@ -1084,6 +1179,97 @@ export const Icons = {
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
StatusError: (props: IconProps) => (
|
||||
<svg
|
||||
width="24px"
|
||||
height="24px"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<g
|
||||
id="StatusAlert"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
>
|
||||
<rect
|
||||
id="Rectangle"
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
></rect>
|
||||
<circle
|
||||
id="Oval"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="8"
|
||||
></circle>
|
||||
<g
|
||||
id="Group"
|
||||
transform="translate(11.5, 8)"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line
|
||||
x1="0.502969489"
|
||||
y1="5"
|
||||
x2="0.502969489"
|
||||
y2="5.55111512e-16"
|
||||
id="Path"
|
||||
></line>
|
||||
<path
|
||||
d="M0.494019489,7.75 C0.427967985,7.75102315 0.365128544,7.77867594 0.319754003,7.82668634 C0.274379462,7.87469675 0.250315262,7.93899595 0.253019489,8.005 C0.257853669,8.14136674 0.369567839,8.24954844 0.506019489,8.25 L0.506019489,8.25 C0.57198073,8.2487037 0.634656968,8.22096694 0.679972815,8.17301863 C0.725288662,8.12507033 0.749445908,8.06092934 0.747019489,7.995 C0.742888429,7.86182395 0.636177529,7.75467571 0.503019489,7.75 L0.498019489,7.75"
|
||||
id="Path"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
StatusSuccess: (props: IconProps) => (
|
||||
<svg
|
||||
width="24px"
|
||||
height="24px"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<g
|
||||
id="StatusSuccess"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
>
|
||||
<rect
|
||||
id="Rectangle"
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
></rect>
|
||||
<polyline
|
||||
id="Path"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
points="16.173913 8.52173913 11.3043478 15.1304348 7.82608696 12.3478261"
|
||||
></polyline>
|
||||
<circle
|
||||
id="Oval"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="8"
|
||||
></circle>
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
StatusTracking: (props: IconProps) => (
|
||||
<svg
|
||||
width="24px"
|
||||
@@ -1290,6 +1476,50 @@ export const Icons = {
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
LoadingSpinner: (props: IconProps) => (
|
||||
<svg
|
||||
role="status"
|
||||
aria-label="Loading"
|
||||
className={`h-5 w-5 animate-spin ${props.className}`}
|
||||
width="24px"
|
||||
height="24px"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<g
|
||||
id="LoadingSpinner"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
>
|
||||
<rect
|
||||
id="Rectangle"
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
></rect>
|
||||
<g
|
||||
id="Group"
|
||||
transform="translate(1, 1)"
|
||||
fillRule="nonzero"
|
||||
>
|
||||
<path
|
||||
d="M11,0 C17.0751322,0 22,4.92486775 22,11 C22,17.0751322 17.0751322,22 11,22 C4.92486775,22 0,17.0751322 0,11 C0,4.92486775 4.92486775,0 11,0 Z M11,2 C6.02943725,2 2,6.02943725 2,11 C2,15.9705627 6.02943725,20 11,20 C15.9705627,20 20,15.9705627 20,11 C20,6.02943725 15.9705627,2 11,2 Z"
|
||||
id="Oval"
|
||||
fill="#348CFD"
|
||||
opacity="0.25"
|
||||
></path>
|
||||
<path
|
||||
d="M19.0287175,4.94590384 C19.5005019,4.65878387 20.1157155,4.80848402 20.4028355,5.28026847 C21.4419642,6.98772474 22,8.94986784 22,10.9915479 C22,17.0666801 17.0751322,21.9915479 11,21.9915479 C10.4477153,21.9915479 10,21.5438326 10,20.9915479 C10,20.4392631 10.4477153,19.9915479 11,19.9915479 C15.9705627,19.9915479 20,15.9621106 20,10.9915479 C20,9.31924154 19.5441371,7.7163545 18.6943528,6.32002184 C18.4072329,5.84823739 18.556933,5.2330238 19.0287175,4.94590384 Z"
|
||||
id="Oval"
|
||||
fill="#5ACCE6"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
NavigationPanelReveal: (props: IconProps) => (
|
||||
<svg
|
||||
width="17"
|
||||
@@ -1311,6 +1541,48 @@ export const Icons = {
|
||||
</svg>
|
||||
),
|
||||
MissingIcon: (props: IconProps) => <div>Missing icon</div>,
|
||||
Series: (props: IconProps) => (
|
||||
<svg
|
||||
width="24px"
|
||||
height="24px"
|
||||
viewBox="0 0 24 24"
|
||||
{...props}
|
||||
>
|
||||
<g
|
||||
id="Series"
|
||||
stroke="none"
|
||||
strokeWidth="1"
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
>
|
||||
<rect
|
||||
id="Rectangle"
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
height="24"
|
||||
></rect>
|
||||
<path
|
||||
d="M8.17391304,15.826087 L4.69565217,15.826087 C4.31145409,15.826087 4,15.5146329 4,15.1304348 L4,4.69565217 C4,4.31145409 4.31145409,4 4.69565217,4 L15.1304348,4 C15.5146329,4 15.826087,4.31145409 15.826087,4.69565217 L15.826087,8.17391304"
|
||||
id="Path"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
></path>
|
||||
<rect
|
||||
id="Rectangle"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
x="8.17391304"
|
||||
y="8.17391304"
|
||||
width="11.826087"
|
||||
height="11.826087"
|
||||
rx="1"
|
||||
></rect>
|
||||
</g>
|
||||
</svg>
|
||||
),
|
||||
Settings: (props: IconProps) => (
|
||||
<svg
|
||||
width="15.7826087px"
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { Toaster as Sonner } from 'sonner';
|
||||
import { Icons } from '../Icons';
|
||||
|
||||
type ToasterProps = React.ComponentProps<typeof Sonner>;
|
||||
|
||||
const Toaster = ({ ...props }: ToasterProps) => {
|
||||
return (
|
||||
<Sonner
|
||||
className="toaster group"
|
||||
loadingIcon={<Icons.LoadingSpinner />}
|
||||
icons={{
|
||||
warning: <Icons.StatusWarning />,
|
||||
info: <Icons.Info className="text-secondary-foreground" />,
|
||||
success: <Icons.StatusSuccess />,
|
||||
error: <Icons.StatusError />,
|
||||
}}
|
||||
theme="dark"
|
||||
richColors="true"
|
||||
toastOptions={{
|
||||
classNames: {
|
||||
toast:
|
||||
'group toast group-[.toaster]:bg-popover group-[.toaster]:text-foreground group-[.toaster]:border-background group-[.toaster]:shadow-lg',
|
||||
info: 'group-[.toast] group-[.toaster]:!bg-popover group-[.toaster]:!text-foreground group-[.toaster]:!border-background',
|
||||
error: 'group-[.toaster]:!border-background',
|
||||
success: 'group-[.toaster]:!border-background',
|
||||
warning: 'group-[.toaster]:!border-background',
|
||||
description: 'group-[.toast]:text-secondary-foreground',
|
||||
actionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',
|
||||
cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',
|
||||
},
|
||||
}}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export { Toaster };
|
||||
@@ -0,0 +1,4 @@
|
||||
import { Toaster } from './Sonner';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
export { Toaster, toast };
|
||||
@@ -71,6 +71,7 @@ import {
|
||||
import { Onboarding } from './Onboarding';
|
||||
import { BackgroundColorSelect } from './BackgroundColorSelect';
|
||||
import { DataRow } from './DataRow';
|
||||
import { Toaster } from './Sonner';
|
||||
|
||||
export {
|
||||
Button,
|
||||
@@ -157,4 +158,5 @@ export {
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
Toaster,
|
||||
};
|
||||
@@ -146,7 +146,7 @@
|
||||
--muted-foreground: 220 8.9% 46.1%;
|
||||
--accent: 220 14.3% 95.9%;
|
||||
--accent-foreground: 220.9 39.3% 11%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive: 360 84.2% 60.2%;
|
||||
--destructive-foreground: 210 20% 98%;
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
@@ -174,7 +174,7 @@
|
||||
--muted-foreground: 217.9 10.6% 64.9%;
|
||||
--accent: 215 27.9% 16.9%;
|
||||
--accent-foreground: 210 20% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive: 360 84.2% 60.2%;
|
||||
--destructive-foreground: 210 20% 98%;
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
|
||||
Reference in new issue
Block a user