Revert "Unify workspace dropdowns; Update layouts (#458)"
This reverts commit 4bc8448a1d.
This commit is contained in:
@@ -120,7 +120,9 @@ export function AlertDialogStory() {
|
||||
|
||||
const generateCode = () => {
|
||||
let code = `<AlertDialog>\n`;
|
||||
code += ` <AlertDialogTrigger render={<Button variant="${controls.triggerVariant}">${controls.triggerText}</Button>} />\n`;
|
||||
code += ` <AlertDialogTrigger asChild>\n`;
|
||||
code += ` <Button variant="${controls.triggerVariant}">${controls.triggerText}</Button>\n`;
|
||||
code += ` </AlertDialogTrigger>\n`;
|
||||
code += ` <AlertDialogContent>\n`;
|
||||
code += ` <AlertDialogHeader>\n`;
|
||||
|
||||
@@ -177,14 +179,11 @@ export function AlertDialogStory() {
|
||||
const renderPreview = () => {
|
||||
return (
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger
|
||||
render={
|
||||
<Button variant={controls.triggerVariant}>
|
||||
{controls.triggerText}
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant={controls.triggerVariant}>
|
||||
{controls.triggerText}
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
{controls.withIcon ? (
|
||||
@@ -342,11 +341,11 @@ export function AlertDialogStory() {
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger
|
||||
render={<Button variant="destructive" size="sm" />}
|
||||
>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete Item
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="destructive" size="sm">
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete Item
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -371,9 +370,11 @@ export function AlertDialogStory() {
|
||||
</AlertDialog>
|
||||
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger render={<Button variant="outline" />}>
|
||||
<LogOut className="mr-2 h-4 w-4" />
|
||||
Sign Out
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<LogOut className="mr-2 h-4 w-4" />
|
||||
Sign Out
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -396,9 +397,11 @@ export function AlertDialogStory() {
|
||||
</AlertDialog>
|
||||
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger render={<Button variant="outline" />}>
|
||||
<UserX className="mr-2 h-4 w-4" />
|
||||
Remove User
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<UserX className="mr-2 h-4 w-4" />
|
||||
Remove User
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -435,9 +438,11 @@ export function AlertDialogStory() {
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger render={<Button variant="outline" />}>
|
||||
<Archive className="mr-2 h-4 w-4" />
|
||||
Archive Project
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Archive className="mr-2 h-4 w-4" />
|
||||
Archive Project
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -460,9 +465,11 @@ export function AlertDialogStory() {
|
||||
</AlertDialog>
|
||||
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger render={<Button />}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export Data
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Export Data
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -486,9 +493,11 @@ export function AlertDialogStory() {
|
||||
</AlertDialog>
|
||||
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger render={<Button variant="outline" />}>
|
||||
<RefreshCw className="mr-2 h-4 w-4" />
|
||||
Reset Settings
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<RefreshCw className="mr-2 h-4 w-4" />
|
||||
Reset Settings
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -526,11 +535,11 @@ export function AlertDialogStory() {
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-sm font-semibold">Error/Destructive</h4>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger
|
||||
render={<Button variant="destructive" size="sm" />}
|
||||
>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete Forever
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="destructive" size="sm">
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete Forever
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -558,11 +567,11 @@ export function AlertDialogStory() {
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-sm font-semibold">Warning</h4>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger
|
||||
render={<Button variant="outline" size="sm" />}
|
||||
>
|
||||
<AlertTriangle className="mr-2 h-4 w-4" />
|
||||
Unsaved Changes
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
<AlertTriangle className="mr-2 h-4 w-4" />
|
||||
Unsaved Changes
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -588,11 +597,11 @@ export function AlertDialogStory() {
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-sm font-semibold">Info</h4>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger
|
||||
render={<Button variant="outline" size="sm" />}
|
||||
>
|
||||
<Share className="mr-2 h-4 w-4" />
|
||||
Share Publicly
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
<Share className="mr-2 h-4 w-4" />
|
||||
Share Publicly
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
@@ -618,9 +627,11 @@ export function AlertDialogStory() {
|
||||
<div className="space-y-3">
|
||||
<h4 className="text-sm font-semibold">Success</h4>
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger render={<Button size="sm" />}>
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Complete Setup
|
||||
<AlertDialogTrigger asChild>
|
||||
<Button size="sm">
|
||||
<Download className="mr-2 h-4 w-4" />
|
||||
Complete Setup
|
||||
</Button>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
|
||||
@@ -33,6 +33,7 @@ interface ButtonControls {
|
||||
loading: boolean;
|
||||
withIcon: boolean;
|
||||
fullWidth: boolean;
|
||||
asChild: boolean;
|
||||
}
|
||||
|
||||
const variantOptions = [
|
||||
@@ -67,6 +68,7 @@ export function ButtonStory() {
|
||||
loading: false,
|
||||
withIcon: false,
|
||||
fullWidth: false,
|
||||
asChild: false,
|
||||
});
|
||||
|
||||
const generateCode = () => {
|
||||
@@ -75,12 +77,14 @@ export function ButtonStory() {
|
||||
variant: controls.variant,
|
||||
size: controls.size,
|
||||
disabled: controls.disabled,
|
||||
asChild: controls.asChild,
|
||||
className: controls.fullWidth ? 'w-full' : '',
|
||||
},
|
||||
{
|
||||
variant: 'default',
|
||||
size: 'default',
|
||||
disabled: false,
|
||||
asChild: false,
|
||||
className: '',
|
||||
},
|
||||
);
|
||||
@@ -190,6 +194,15 @@ export function ButtonStory() {
|
||||
onCheckedChange={(checked) => updateControl('fullWidth', checked)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="asChild">As Child</Label>
|
||||
<Switch
|
||||
id="asChild"
|
||||
checked={controls.asChild}
|
||||
onCheckedChange={(checked) => updateControl('asChild', checked)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
|
||||
@@ -276,11 +276,11 @@ export default function CalendarStory() {
|
||||
<Card>
|
||||
<CardContent className="flex justify-center pt-6">
|
||||
<Popover>
|
||||
<PopoverTrigger
|
||||
render={<Button variant="outline" className="justify-start" />}
|
||||
>
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
Pick a date
|
||||
<PopoverTrigger asChild>
|
||||
<Button variant="outline" className="justify-start">
|
||||
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||
Pick a date
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0" align="start">
|
||||
<Calendar
|
||||
|
||||
@@ -320,12 +320,10 @@ export function CardButtonStory() {
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="border-b">
|
||||
<td className="p-3 font-mono text-sm">render</td>
|
||||
<td className="p-3 font-mono text-sm">
|
||||
React.ReactElement
|
||||
</td>
|
||||
<td className="p-3 font-mono text-sm">-</td>
|
||||
<td className="p-3">Compose with a custom element</td>
|
||||
<td className="p-3 font-mono text-sm">asChild</td>
|
||||
<td className="p-3 font-mono text-sm">boolean</td>
|
||||
<td className="p-3 font-mono text-sm">false</td>
|
||||
<td className="p-3">Render as child element</td>
|
||||
</tr>
|
||||
<tr className="border-b">
|
||||
<td className="p-3 font-mono text-sm">className</td>
|
||||
|
||||
@@ -139,8 +139,8 @@ export function DialogStory() {
|
||||
});
|
||||
|
||||
let code = `<Dialog>\n`;
|
||||
code += ` <DialogTrigger render={<Button variant="${controls.triggerVariant}" />}>\n`;
|
||||
code += ` ${controls.triggerText}\n`;
|
||||
code += ` <DialogTrigger asChild>\n`;
|
||||
code += ` <Button variant="${controls.triggerVariant}">${controls.triggerText}</Button>\n`;
|
||||
code += ` </DialogTrigger>\n`;
|
||||
code += ` <DialogContent${contentPropsString}>\n`;
|
||||
code += ` <DialogHeader>\n`;
|
||||
@@ -182,8 +182,8 @@ export function DialogStory() {
|
||||
|
||||
if (controls.withFooter) {
|
||||
code += ` <DialogFooter>\n`;
|
||||
code += ` <DialogClose render={<Button variant="outline" />}>\n`;
|
||||
code += ` Cancel\n`;
|
||||
code += ` <DialogClose asChild>\n`;
|
||||
code += ` <Button variant="outline">Cancel</Button>\n`;
|
||||
code += ` </DialogClose>\n`;
|
||||
code += ` <Button>Save Changes</Button>\n`;
|
||||
code += ` </DialogFooter>\n`;
|
||||
@@ -198,8 +198,10 @@ export function DialogStory() {
|
||||
const renderPreview = () => {
|
||||
return (
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button variant={controls.triggerVariant} />}>
|
||||
{controls.triggerText}
|
||||
<DialogTrigger asChild>
|
||||
<Button variant={controls.triggerVariant}>
|
||||
{controls.triggerText}
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent
|
||||
className={cn(
|
||||
@@ -269,8 +271,8 @@ export function DialogStory() {
|
||||
|
||||
{controls.withFooter && (
|
||||
<DialogFooter>
|
||||
<DialogClose render={<Button variant="outline" />}>
|
||||
Cancel
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Cancel</Button>
|
||||
</DialogClose>
|
||||
<Button>Save Changes</Button>
|
||||
</DialogFooter>
|
||||
@@ -389,9 +391,11 @@ export function DialogStory() {
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button variant="outline" />}>
|
||||
<Info className="mr-2 h-4 w-4" />
|
||||
Info Dialog
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Info className="mr-2 h-4 w-4" />
|
||||
Info Dialog
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
@@ -408,15 +412,19 @@ export function DialogStory() {
|
||||
</p>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose render={<Button />}>Got it</DialogClose>
|
||||
<DialogClose asChild>
|
||||
<Button>Got it</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button />}>
|
||||
<Edit className="mr-2 h-4 w-4" />
|
||||
Edit Profile
|
||||
<DialogTrigger asChild>
|
||||
<Button>
|
||||
<Edit className="mr-2 h-4 w-4" />
|
||||
Edit Profile
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
@@ -448,8 +456,8 @@ export function DialogStory() {
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose render={<Button variant="outline" />}>
|
||||
Cancel
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Cancel</Button>
|
||||
</DialogClose>
|
||||
<Button>Save Changes</Button>
|
||||
</DialogFooter>
|
||||
@@ -457,9 +465,11 @@ export function DialogStory() {
|
||||
</Dialog>
|
||||
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button variant="secondary" />}>
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
Settings
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="secondary">
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
Settings
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
@@ -489,8 +499,8 @@ export function DialogStory() {
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose render={<Button variant="outline" />}>
|
||||
Cancel
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Cancel</Button>
|
||||
</DialogClose>
|
||||
<Button>Save</Button>
|
||||
</DialogFooter>
|
||||
@@ -508,8 +518,10 @@ export function DialogStory() {
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button variant="outline" size="sm" />}>
|
||||
Small Dialog
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
Small Dialog
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-md">
|
||||
<DialogHeader>
|
||||
@@ -524,14 +536,16 @@ export function DialogStory() {
|
||||
</p>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose render={<Button />}>Close</DialogClose>
|
||||
<DialogClose asChild>
|
||||
<Button>Close</Button>
|
||||
</DialogClose>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button variant="outline" />}>
|
||||
Large Dialog
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline">Large Dialog</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogHeader>
|
||||
@@ -557,8 +571,8 @@ export function DialogStory() {
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose render={<Button variant="outline" />}>
|
||||
Cancel
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Cancel</Button>
|
||||
</DialogClose>
|
||||
<Button>Save</Button>
|
||||
</DialogFooter>
|
||||
@@ -576,9 +590,11 @@ export function DialogStory() {
|
||||
<CardContent className="space-y-4">
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button variant="outline" />}>
|
||||
<Image className="mr-2 h-4 w-4" />
|
||||
Image Gallery
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Image className="mr-2 h-4 w-4" />
|
||||
Image Gallery
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogHeader>
|
||||
@@ -611,9 +627,11 @@ export function DialogStory() {
|
||||
</Dialog>
|
||||
|
||||
<Dialog>
|
||||
<DialogTrigger render={<Button variant="outline" />}>
|
||||
<MessageSquare className="mr-2 h-4 w-4" />
|
||||
Feedback
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<MessageSquare className="mr-2 h-4 w-4" />
|
||||
Feedback
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
@@ -650,8 +668,8 @@ export function DialogStory() {
|
||||
</div>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose render={<Button variant="outline" />}>
|
||||
Cancel
|
||||
<DialogClose asChild>
|
||||
<Button variant="outline">Cancel</Button>
|
||||
</DialogClose>
|
||||
<Button>
|
||||
<MessageSquare className="mr-2 h-4 w-4" />
|
||||
@@ -718,8 +736,8 @@ export function DialogStory() {
|
||||
<div>
|
||||
<h4 className="mb-3 text-lg font-semibold">DialogTrigger</h4>
|
||||
<p className="text-muted-foreground mb-3 text-sm">
|
||||
The element that opens the dialog. Use the render prop to compose
|
||||
with a custom element.
|
||||
The element that opens the dialog. Use asChild prop to render as
|
||||
child element.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import { Code2, FileText, Search } from 'lucide-react';
|
||||
|
||||
@@ -35,7 +35,6 @@ export function DocsSidebar({
|
||||
selectedCategory,
|
||||
}: DocsSidebarProps) {
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
|
||||
const filteredComponents = COMPONENTS_REGISTRY.filter((c) =>
|
||||
@@ -51,21 +50,21 @@ export function DocsSidebar({
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
const onCategorySelect = (category: string | null) => {
|
||||
const sp = new URLSearchParams(searchParams);
|
||||
sp.set('category', category || '');
|
||||
router.push(`/components?${sp.toString()}`);
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
searchParams.set('category', category || '');
|
||||
router.push(`/components?${searchParams.toString()}`);
|
||||
};
|
||||
|
||||
const onComponentSelect = (component: ComponentInfo) => {
|
||||
const sp = new URLSearchParams(searchParams);
|
||||
sp.set('component', component.name);
|
||||
router.push(`/components?${sp.toString()}`);
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
searchParams.set('component', component.name);
|
||||
router.push(`/components?${searchParams.toString()}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-muted/30 flex h-screen w-80 flex-col overflow-hidden border-r">
|
||||
{/* Header */}
|
||||
<div className="shrink-0 border-b p-4">
|
||||
<div className="flex-shrink-0 border-b p-4">
|
||||
<div className="mb-2 flex items-center gap-2">
|
||||
<Code2 className="text-primary h-6 w-6" />
|
||||
|
||||
@@ -78,14 +77,13 @@ export function DocsSidebar({
|
||||
</div>
|
||||
|
||||
{/* Controls */}
|
||||
<div className="shrink-0 space-y-2 border-b p-4">
|
||||
<div className="flex-shrink-0 space-y-2 border-b p-4">
|
||||
{/* Category Select */}
|
||||
<div className="space-y-2">
|
||||
<Select
|
||||
defaultValue={selectedCategory || 'all'}
|
||||
value={selectedCategory || 'all'}
|
||||
onValueChange={(value) => {
|
||||
const category = value === 'all' ? null : value;
|
||||
|
||||
onCategorySelect(category);
|
||||
|
||||
// Select first component in the filtered results
|
||||
@@ -98,12 +96,8 @@ export function DocsSidebar({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SelectTrigger className="w-full">
|
||||
<SelectValue>
|
||||
{(category) => {
|
||||
return category === 'all' ? 'All Categories' : category;
|
||||
}}
|
||||
</SelectValue>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder={'Select a category'} />
|
||||
</SelectTrigger>
|
||||
|
||||
<SelectContent>
|
||||
@@ -160,7 +154,7 @@ export function DocsSidebar({
|
||||
|
||||
{/* Components List - Scrollable */}
|
||||
<div className="flex flex-1 flex-col overflow-y-auto">
|
||||
<div className="shrink-0 p-4 pb-2">
|
||||
<div className="flex-shrink-0 p-4 pb-2">
|
||||
<h3 className="flex items-center gap-2 text-sm font-semibold">
|
||||
<FileText className="h-4 w-4" />
|
||||
Components
|
||||
|
||||
@@ -101,18 +101,13 @@ const examples = [
|
||||
return (
|
||||
<div className="flex min-h-32 items-center justify-center">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="relative h-8 w-8 rounded-full"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src="/avatars/01.png" alt="@username" />
|
||||
<AvatarFallback>JD</AvatarFallback>
|
||||
</Avatar>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="relative h-8 w-8 rounded-full">
|
||||
<Avatar className="h-8 w-8">
|
||||
<AvatarImage src="/avatars/01.png" alt="@username" />
|
||||
<AvatarFallback>JD</AvatarFallback>
|
||||
</Avatar>
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56" align="end" forceMount>
|
||||
<DropdownMenuLabel className="font-normal">
|
||||
@@ -190,11 +185,11 @@ const examples = [
|
||||
</div>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={<Button variant="ghost" className="h-8 w-8 p-0" />}
|
||||
>
|
||||
<span className="sr-only">Open menu</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||
<span className="sr-only">Open menu</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-48">
|
||||
<DropdownMenuItem onClick={() => setSelectedAction('open')}>
|
||||
@@ -280,9 +275,11 @@ const examples = [
|
||||
return (
|
||||
<div className="flex min-h-48 items-center justify-center">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger render={<Button variant="outline" />}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create New
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Create New
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-56">
|
||||
<DropdownMenuLabel>Create Content</DropdownMenuLabel>
|
||||
@@ -396,11 +393,11 @@ const examples = [
|
||||
<span className="text-sm">Appearance & Layout</span>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={<Button variant="outline" size="sm" />}
|
||||
>
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
Configure
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
Configure
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-64" align="end">
|
||||
<DropdownMenuLabel>View Options</DropdownMenuLabel>
|
||||
@@ -550,10 +547,10 @@ const examples = [
|
||||
</div>
|
||||
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={<Button variant="ghost" className="h-8 w-8 p-0" />}
|
||||
>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-48">
|
||||
<DropdownMenuItem
|
||||
@@ -866,7 +863,7 @@ export default function DropdownMenuStory() {
|
||||
modal: controls.modal ? true : undefined,
|
||||
});
|
||||
|
||||
const dropdownStructure = `<DropdownMenu${rootProps}>\n <DropdownMenuTrigger render={<Button variant="outline" />}>\n Open Menu\n </DropdownMenuTrigger>\n <DropdownMenuContent${contentProps}>\n <DropdownMenuItem>\n <User className="mr-2 h-4 w-4" />\n <span>Profile</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Settings className="mr-2 h-4 w-4" />\n <span>Settings</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut className="mr-2 h-4 w-4" />\n <span>Log out</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n</DropdownMenu>`;
|
||||
const dropdownStructure = `<DropdownMenu${rootProps}>\n <DropdownMenuTrigger asChild>\n <Button variant="outline">Open Menu</Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent${contentProps}>\n <DropdownMenuItem>\n <User className="mr-2 h-4 w-4" />\n <span>Profile</span>\n </DropdownMenuItem>\n <DropdownMenuItem>\n <Settings className="mr-2 h-4 w-4" />\n <span>Settings</span>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <LogOut className="mr-2 h-4 w-4" />\n <span>Log out</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n</DropdownMenu>`;
|
||||
|
||||
return `${importStatement}\n${buttonImport}\n${iconImport}\n\n${dropdownStructure}`;
|
||||
};
|
||||
@@ -974,8 +971,8 @@ export default function DropdownMenuStory() {
|
||||
const previewContent = (
|
||||
<div className="flex justify-center p-6">
|
||||
<DropdownMenu modal={controls.modal}>
|
||||
<DropdownMenuTrigger render={<Button variant="outline" />}>
|
||||
Open Menu
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline">Open Menu</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
side={controls.side}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useState } from 'react';
|
||||
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import * as z from 'zod';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Badge } from '@kit/ui/badge';
|
||||
import { Button } from '@kit/ui/button';
|
||||
@@ -119,7 +119,7 @@ export default function FormStory() {
|
||||
const formImport = generateImportStatement(formComponents, '@kit/ui/form');
|
||||
const inputImport = generateImportStatement(['Input'], '@kit/ui/input');
|
||||
const buttonImport = generateImportStatement(['Button'], '@kit/ui/button');
|
||||
const hookFormImports = `import { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as z from 'zod';`;
|
||||
const hookFormImports = `import { useForm } from 'react-hook-form';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { z } from 'zod';`;
|
||||
|
||||
let schemaCode = '';
|
||||
let formFieldsCode = '';
|
||||
@@ -130,19 +130,19 @@ export default function FormStory() {
|
||||
|
||||
formFieldsCode = ` <FormField\n control={form.control}\n name="username"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Username</FormLabel>\n <FormControl>\n <Input ${controls.disabled ? 'disabled ' : ''}placeholder="Enter username" {...field} />\n </FormControl>${controls.showDescriptions ? '\n <FormDescription>\n Your public display name.\n </FormDescription>' : ''}${controls.showValidation ? '\n <FormMessage />' : ''}\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name="email"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Email</FormLabel>\n <FormControl>\n <Input ${controls.disabled ? 'disabled ' : ''}type="email" placeholder="Enter email" {...field} />\n </FormControl>${controls.showDescriptions ? "\n <FormDescription>\n We'll never share your email.\n </FormDescription>" : ''}${controls.showValidation ? '\n <FormMessage />' : ''}\n </FormItem>\n )}\n />`;
|
||||
|
||||
onSubmitCode = ` function onSubmit(values: z.output<typeof formSchema>) {\n console.log('Form submitted:', values);\n }`;
|
||||
onSubmitCode = ` function onSubmit(values: z.infer<typeof formSchema>) {\n console.log('Form submitted:', values);\n }`;
|
||||
} else if (controls.formType === 'advanced') {
|
||||
schemaCode = `const formSchema = z.object({\n firstName: z.string().min(1, 'First name is required.'),\n lastName: z.string().min(1, 'Last name is required.'),\n email: z.string().email('Please enter a valid email address.'),\n});`;
|
||||
|
||||
formFieldsCode = ` <FormField\n control={form.control}\n name="firstName"\n render={({ field }) => (\n <FormItem>\n <FormLabel>First Name</FormLabel>\n <FormControl>\n <Input ${controls.disabled ? 'disabled ' : ''}placeholder="John" {...field} />\n </FormControl>${controls.showValidation ? '\n <FormMessage />' : ''}\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name="lastName"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Last Name</FormLabel>\n <FormControl>\n <Input ${controls.disabled ? 'disabled ' : ''}placeholder="Doe" {...field} />\n </FormControl>${controls.showValidation ? '\n <FormMessage />' : ''}\n </FormItem>\n )}\n />`;
|
||||
|
||||
onSubmitCode = ` function onSubmit(values: z.output<typeof formSchema>) {\n console.log('Advanced form submitted:', values);\n }`;
|
||||
onSubmitCode = ` function onSubmit(values: z.infer<typeof formSchema>) {\n console.log('Advanced form submitted:', values);\n }`;
|
||||
} else {
|
||||
schemaCode = `const formSchema = z.object({\n password: z.string().min(8, 'Password must be at least 8 characters.'),\n confirmPassword: z.string(),\n}).refine((data) => data.password === data.confirmPassword, {\n message: 'Passwords do not match.',\n path: ['confirmPassword'],\n});`;
|
||||
|
||||
formFieldsCode = ` <FormField\n control={form.control}\n name="password"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Password</FormLabel>\n <FormControl>\n <Input ${controls.disabled ? 'disabled ' : ''}type="password" {...field} />\n </FormControl>${controls.showValidation ? '\n <FormMessage />' : ''}\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name="confirmPassword"\n render={({ field }) => (\n <FormItem>\n <FormLabel>Confirm Password</FormLabel>\n <FormControl>\n <Input ${controls.disabled ? 'disabled ' : ''}type="password" {...field} />\n </FormControl>${controls.showValidation ? '\n <FormMessage />' : ''}\n </FormItem>\n )}\n />`;
|
||||
|
||||
onSubmitCode = ` function onSubmit(values: z.output<typeof formSchema>) {\n console.log('Validation form submitted:', values);\n }`;
|
||||
onSubmitCode = ` function onSubmit(values: z.infer<typeof formSchema>) {\n console.log('Validation form submitted:', values);\n }`;
|
||||
}
|
||||
|
||||
const defaultValuesCode =
|
||||
@@ -152,13 +152,13 @@ export default function FormStory() {
|
||||
? ` defaultValues: {\n firstName: '',\n lastName: '',\n email: '',\n },`
|
||||
: ` defaultValues: {\n password: '',\n confirmPassword: '',\n },`;
|
||||
|
||||
const fullFormCode = `${hookFormImports}\n${formImport}\n${inputImport}\n${buttonImport}\n\n${schemaCode}\n\nfunction MyForm() {\n const form = useForm<z.output<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n${defaultValuesCode}\n });\n\n${onSubmitCode}\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">\n${formFieldsCode}\n <Button type="submit"${controls.disabled ? ' disabled' : ''}>Submit</Button>\n </form>\n </Form>\n );\n}`;
|
||||
const fullFormCode = `${hookFormImports}\n${formImport}\n${inputImport}\n${buttonImport}\n\n${schemaCode}\n\nfunction MyForm() {\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n${defaultValuesCode}\n });\n\n${onSubmitCode}\n\n return (\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">\n${formFieldsCode}\n <Button type="submit"${controls.disabled ? ' disabled' : ''}>Submit</Button>\n </form>\n </Form>\n );\n}`;
|
||||
|
||||
return fullFormCode;
|
||||
};
|
||||
|
||||
// Basic form
|
||||
const basicForm = useForm<z.output<typeof basicFormSchema>>({
|
||||
const basicForm = useForm<z.infer<typeof basicFormSchema>>({
|
||||
resolver: zodResolver(basicFormSchema),
|
||||
defaultValues: {
|
||||
username: '',
|
||||
@@ -169,7 +169,7 @@ export default function FormStory() {
|
||||
});
|
||||
|
||||
// Advanced form
|
||||
const advancedForm = useForm<z.output<typeof advancedFormSchema>>({
|
||||
const advancedForm = useForm<z.infer<typeof advancedFormSchema>>({
|
||||
resolver: zodResolver(advancedFormSchema),
|
||||
defaultValues: {
|
||||
firstName: '',
|
||||
@@ -183,7 +183,7 @@ export default function FormStory() {
|
||||
});
|
||||
|
||||
// Validation form
|
||||
const validationForm = useForm<z.output<typeof validationFormSchema>>({
|
||||
const validationForm = useForm<z.infer<typeof validationFormSchema>>({
|
||||
resolver: zodResolver(validationFormSchema),
|
||||
defaultValues: {
|
||||
password: '',
|
||||
@@ -1056,7 +1056,7 @@ export default function FormStory() {
|
||||
<pre className="overflow-x-auto text-sm">
|
||||
{`import { useForm } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import * as z from 'zod';
|
||||
import { z } from 'zod';
|
||||
import { Form, FormField, FormItem, FormLabel, FormControl, FormMessage } from '@kit/ui/form';
|
||||
|
||||
const formSchema = z.object({
|
||||
@@ -1065,7 +1065,7 @@ const formSchema = z.object({
|
||||
});
|
||||
|
||||
function MyForm() {
|
||||
const form = useForm<z.output<typeof formSchema>>({
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
username: '',
|
||||
@@ -1073,7 +1073,7 @@ function MyForm() {
|
||||
},
|
||||
});
|
||||
|
||||
function onSubmit(values: z.output<typeof formSchema>) {
|
||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
console.log(values);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ export function KbdStory() {
|
||||
let snippet = groupLines.join('\n');
|
||||
|
||||
if (controls.showTooltip) {
|
||||
snippet = `<TooltipProvider>\n <Tooltip>\n <TooltipTrigger render={<Button variant="outline" />}>\n Command palette\n </TooltipTrigger>\n <TooltipContent className="flex items-center gap-2">\n <span>Press</span>\n ${groupLines.join('\n ')}\n </TooltipContent>\n </Tooltip>\n</TooltipProvider>`;
|
||||
snippet = `<TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button variant="outline">Command palette</Button>\n </TooltipTrigger>\n <TooltipContent className="flex items-center gap-2">\n <span>Press</span>\n ${groupLines.join('\n ')}\n </TooltipContent>\n </Tooltip>\n</TooltipProvider>`;
|
||||
}
|
||||
|
||||
return formatCodeBlock(snippet, [
|
||||
@@ -115,11 +115,11 @@ export function KbdStory() {
|
||||
{controls.showTooltip ? (
|
||||
<TooltipProvider delayDuration={200}>
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button variant="outline" className="gap-2" />}
|
||||
>
|
||||
<Command className="h-4 w-4" />
|
||||
Command palette
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline" className="gap-2">
|
||||
<Command className="h-4 w-4" />
|
||||
Command palette
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="flex items-center gap-2">
|
||||
<span>Press</span>
|
||||
|
||||
@@ -136,13 +136,11 @@ export function SimpleDataTableStory() {
|
||||
{controls.showActions && (
|
||||
<TableCell>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button variant="ghost" className="h-8 w-8 p-0" />
|
||||
}
|
||||
>
|
||||
<span className="sr-only">Open menu</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0">
|
||||
<span className="sr-only">Open menu</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem
|
||||
|
||||
@@ -100,7 +100,7 @@ export function SwitchStory() {
|
||||
className: cn(
|
||||
controls.size === 'sm' && 'h-4 w-7',
|
||||
controls.size === 'lg' && 'h-6 w-11',
|
||||
controls.error && 'data-checked:bg-destructive',
|
||||
controls.error && 'data-[state=checked]:bg-destructive',
|
||||
),
|
||||
};
|
||||
|
||||
@@ -200,7 +200,7 @@ export function SwitchStory() {
|
||||
className={cn(
|
||||
controls.size === 'sm' && 'h-4 w-7',
|
||||
controls.size === 'lg' && 'h-6 w-11',
|
||||
controls.error && 'data-checked:bg-destructive',
|
||||
controls.error && 'data-[state=checked]:bg-destructive',
|
||||
)}
|
||||
/>
|
||||
);
|
||||
@@ -616,7 +616,7 @@ export function SwitchStory() {
|
||||
</Label>
|
||||
<Switch
|
||||
id="error-switch"
|
||||
className="data-checked:bg-destructive"
|
||||
className="data-[state=checked]:bg-destructive"
|
||||
/>
|
||||
</div>
|
||||
<p className="text-destructive text-sm">
|
||||
@@ -642,7 +642,7 @@ export function SwitchStory() {
|
||||
<div>
|
||||
<h4 className="mb-3 text-lg font-semibold">Switch</h4>
|
||||
<p className="text-muted-foreground mb-3 text-sm">
|
||||
A toggle switch component for boolean states. Built on Base UI
|
||||
A toggle switch component for boolean states. Built on Radix UI
|
||||
Switch primitive.
|
||||
</p>
|
||||
<div className="overflow-x-auto">
|
||||
|
||||
@@ -62,9 +62,9 @@ interface TabsControlsProps {
|
||||
const variantClasses = {
|
||||
default: '',
|
||||
pills:
|
||||
'[&>div]:bg-background [&>div]:border [&>div]:rounded-lg [&>div]:p-1 [&_button]:rounded-md [&_button[data-active]]:bg-primary [&_button[data-active]]:text-primary-foreground',
|
||||
'[&>div]:bg-background [&>div]:border [&>div]:rounded-lg [&>div]:p-1 [&_button]:rounded-md [&_button[data-state=active]]:bg-primary [&_button[data-state=active]]:text-primary-foreground',
|
||||
underline:
|
||||
'[&>div]:bg-transparent [&>div]:border-b [&>div]:rounded-none [&_button]:rounded-none [&_button]:border-b-2 [&_button]:border-transparent [&_button[data-active]]:border-primary [&_button[data-active]]:bg-transparent',
|
||||
'[&>div]:bg-transparent [&>div]:border-b [&>div]:rounded-none [&_button]:rounded-none [&_button]:border-b-2 [&_button]:border-transparent [&_button[data-state=active]]:border-primary [&_button[data-state=active]]:bg-transparent',
|
||||
};
|
||||
|
||||
const sizeClasses = {
|
||||
@@ -683,28 +683,28 @@ function App() {
|
||||
<TabsList className="h-auto rounded-none border-b bg-transparent p-0">
|
||||
<TabsTrigger
|
||||
value="overview"
|
||||
className="data-active:border-primary rounded-none border-b-2 border-transparent data-active:bg-transparent"
|
||||
className="data-[state=active]:border-primary rounded-none border-b-2 border-transparent data-[state=active]:bg-transparent"
|
||||
>
|
||||
<BarChart3 className="mr-2 h-4 w-4" />
|
||||
Overview
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="users"
|
||||
className="data-active:border-primary rounded-none border-b-2 border-transparent data-active:bg-transparent"
|
||||
className="data-[state=active]:border-primary rounded-none border-b-2 border-transparent data-[state=active]:bg-transparent"
|
||||
>
|
||||
<User className="mr-2 h-4 w-4" />
|
||||
Users
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="revenue"
|
||||
className="data-active:border-primary rounded-none border-b-2 border-transparent data-active:bg-transparent"
|
||||
className="data-[state=active]:border-primary rounded-none border-b-2 border-transparent data-[state=active]:bg-transparent"
|
||||
>
|
||||
<CreditCard className="mr-2 h-4 w-4" />
|
||||
Revenue
|
||||
</TabsTrigger>
|
||||
<TabsTrigger
|
||||
value="reports"
|
||||
className="data-active:border-primary rounded-none border-b-2 border-transparent data-active:bg-transparent"
|
||||
className="data-[state=active]:border-primary rounded-none border-b-2 border-transparent data-[state=active]:bg-transparent"
|
||||
>
|
||||
<FileText className="mr-2 h-4 w-4" />
|
||||
Reports
|
||||
@@ -905,7 +905,8 @@ const apiReference = {
|
||||
{
|
||||
name: '...props',
|
||||
type: 'React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>',
|
||||
description: 'All additional props from Base UI Tabs.Root component.',
|
||||
description:
|
||||
'All props from Radix UI Tabs.Root component including asChild, id, etc.',
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
|
||||
@@ -144,23 +144,22 @@ function TooltipStory() {
|
||||
|
||||
let code = `<TooltipProvider${providerPropsString}>\n`;
|
||||
code += ` <Tooltip>\n`;
|
||||
code += ` <TooltipTrigger asChild>\n`;
|
||||
|
||||
if (controls.triggerType === 'button') {
|
||||
code += ` <TooltipTrigger render={<Button variant="${controls.triggerVariant}" />}>\n`;
|
||||
code += ` Hover me\n`;
|
||||
code += ` <Button variant="${controls.triggerVariant}">Hover me</Button>\n`;
|
||||
} else if (controls.triggerType === 'icon') {
|
||||
code += ` <Button variant="${controls.triggerVariant}" size="icon">\n`;
|
||||
const iconName = selectedIconData?.icon.name || 'Info';
|
||||
code += ` <TooltipTrigger render={<Button variant="${controls.triggerVariant}" size="icon" />}>\n`;
|
||||
code += ` <${iconName} className="h-4 w-4" />\n`;
|
||||
code += ` <${iconName} className="h-4 w-4" />\n`;
|
||||
code += ` </Button>\n`;
|
||||
} else if (controls.triggerType === 'text') {
|
||||
code += ` <TooltipTrigger render={<span className="cursor-help underline decoration-dotted" />}>\n`;
|
||||
code += ` Hover me\n`;
|
||||
code += ` <span className="cursor-help underline decoration-dotted">Hover me</span>\n`;
|
||||
} else if (controls.triggerType === 'input') {
|
||||
code += ` <TooltipTrigger render={<Input placeholder="Hover over this input" />} />\n`;
|
||||
code += ` <Input placeholder="Hover over this input" />\n`;
|
||||
}
|
||||
|
||||
if (controls.triggerType !== 'input') {
|
||||
code += ` </TooltipTrigger>\n`;
|
||||
}
|
||||
code += ` </TooltipTrigger>\n`;
|
||||
code += ` <TooltipContent${contentPropsString}>\n`;
|
||||
code += ` <p>${controls.content}</p>\n`;
|
||||
code += ` </TooltipContent>\n`;
|
||||
@@ -171,50 +170,28 @@ function TooltipStory() {
|
||||
};
|
||||
|
||||
const renderPreview = () => {
|
||||
const renderTrigger = () => {
|
||||
const trigger = (() => {
|
||||
switch (controls.triggerType) {
|
||||
case 'button':
|
||||
return (
|
||||
<TooltipTrigger
|
||||
render={<Button variant={controls.triggerVariant} />}
|
||||
>
|
||||
Hover me
|
||||
</TooltipTrigger>
|
||||
);
|
||||
return <Button variant={controls.triggerVariant}>Hover me</Button>;
|
||||
case 'icon':
|
||||
return (
|
||||
<TooltipTrigger
|
||||
render={<Button variant={controls.triggerVariant} size="icon" />}
|
||||
>
|
||||
<Button variant={controls.triggerVariant} size="icon">
|
||||
<IconComponent className="h-4 w-4" />
|
||||
</TooltipTrigger>
|
||||
</Button>
|
||||
);
|
||||
case 'text':
|
||||
return (
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<span className="cursor-help underline decoration-dotted" />
|
||||
}
|
||||
>
|
||||
<span className="cursor-help underline decoration-dotted">
|
||||
Hover me
|
||||
</TooltipTrigger>
|
||||
</span>
|
||||
);
|
||||
case 'input':
|
||||
return (
|
||||
<TooltipTrigger
|
||||
render={<Input placeholder="Hover over this input" />}
|
||||
/>
|
||||
);
|
||||
return <Input placeholder="Hover over this input" />;
|
||||
default:
|
||||
return (
|
||||
<TooltipTrigger
|
||||
render={<Button variant={controls.triggerVariant} />}
|
||||
>
|
||||
Hover me
|
||||
</TooltipTrigger>
|
||||
);
|
||||
return <Button variant={controls.triggerVariant}>Hover me</Button>;
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
return (
|
||||
<div className="flex min-h-[200px] items-center justify-center">
|
||||
@@ -224,7 +201,7 @@ function TooltipStory() {
|
||||
disableHoverableContent={controls.disableHoverableContent}
|
||||
>
|
||||
<Tooltip>
|
||||
{renderTrigger()}
|
||||
<TooltipTrigger asChild>{trigger}</TooltipTrigger>
|
||||
<TooltipContent
|
||||
side={controls.side}
|
||||
align={controls.align}
|
||||
@@ -399,9 +376,11 @@ function TooltipStory() {
|
||||
<TooltipProvider>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<Tooltip>
|
||||
<TooltipTrigger render={<Button variant="outline" />}>
|
||||
<Info className="mr-2 h-4 w-4" />
|
||||
Info Button
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Info className="mr-2 h-4 w-4" />
|
||||
Info Button
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>This provides additional information</p>
|
||||
@@ -409,8 +388,10 @@ function TooltipStory() {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger render={<Button variant="ghost" size="icon" />}>
|
||||
<HelpCircle className="h-4 w-4" />
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="ghost" size="icon">
|
||||
<HelpCircle className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Click for help documentation</p>
|
||||
@@ -418,12 +399,10 @@ function TooltipStory() {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<span className="cursor-help underline decoration-dotted" />
|
||||
}
|
||||
>
|
||||
Hover for explanation
|
||||
<TooltipTrigger asChild>
|
||||
<span className="cursor-help underline decoration-dotted">
|
||||
Hover for explanation
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>This term needs clarification for better understanding</p>
|
||||
@@ -431,9 +410,9 @@ function TooltipStory() {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Input placeholder="Hover me" className="w-48" />}
|
||||
/>
|
||||
<TooltipTrigger asChild>
|
||||
<Input placeholder="Hover me" className="w-48" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Enter your email address here</p>
|
||||
</TooltipContent>
|
||||
@@ -455,10 +434,10 @@ function TooltipStory() {
|
||||
{/* Top Row */}
|
||||
<div></div>
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button variant="outline" size="sm" />}
|
||||
>
|
||||
Top
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
Top
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="top">
|
||||
<p>Tooltip on top</p>
|
||||
@@ -468,10 +447,10 @@ function TooltipStory() {
|
||||
|
||||
{/* Middle Row */}
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button variant="outline" size="sm" />}
|
||||
>
|
||||
Left
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
Left
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="left">
|
||||
<p>Tooltip on left</p>
|
||||
@@ -481,10 +460,10 @@ function TooltipStory() {
|
||||
<span className="text-muted-foreground text-sm">Center</span>
|
||||
</div>
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button variant="outline" size="sm" />}
|
||||
>
|
||||
Right
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
Right
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="right">
|
||||
<p>Tooltip on right</p>
|
||||
@@ -494,10 +473,10 @@ function TooltipStory() {
|
||||
{/* Bottom Row */}
|
||||
<div></div>
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button variant="outline" size="sm" />}
|
||||
>
|
||||
Bottom
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline" size="sm">
|
||||
Bottom
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">
|
||||
<p>Tooltip on bottom</p>
|
||||
@@ -519,9 +498,11 @@ function TooltipStory() {
|
||||
<TooltipProvider>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<Tooltip>
|
||||
<TooltipTrigger render={<Button variant="outline" />}>
|
||||
<Star className="mr-2 h-4 w-4" />
|
||||
Premium Feature
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Star className="mr-2 h-4 w-4" />
|
||||
Premium Feature
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-xs">
|
||||
<div className="space-y-1">
|
||||
@@ -535,9 +516,11 @@ function TooltipStory() {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger render={<Button variant="outline" />}>
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
Advanced Settings
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="outline">
|
||||
<Settings className="mr-2 h-4 w-4" />
|
||||
Advanced Settings
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<div className="space-y-1">
|
||||
@@ -554,9 +537,11 @@ function TooltipStory() {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger render={<Button variant="destructive" />}>
|
||||
<AlertCircle className="mr-2 h-4 w-4" />
|
||||
Delete Account
|
||||
<TooltipTrigger asChild>
|
||||
<Button variant="destructive">
|
||||
<AlertCircle className="mr-2 h-4 w-4" />
|
||||
Delete Account
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="border-destructive bg-destructive text-destructive-foreground max-w-xs">
|
||||
<div className="space-y-1">
|
||||
@@ -583,10 +568,10 @@ function TooltipStory() {
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center gap-4">
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button size="icon" variant="ghost" />}
|
||||
>
|
||||
<Copy className="h-4 w-4" />
|
||||
<TooltipTrigger asChild>
|
||||
<Button size="icon" variant="ghost">
|
||||
<Copy className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Copy to clipboard</p>
|
||||
@@ -594,10 +579,10 @@ function TooltipStory() {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button size="icon" variant="ghost" />}
|
||||
>
|
||||
<Download className="h-4 w-4" />
|
||||
<TooltipTrigger asChild>
|
||||
<Button size="icon" variant="ghost">
|
||||
<Download className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Download file</p>
|
||||
@@ -605,10 +590,10 @@ function TooltipStory() {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={<Button size="icon" variant="ghost" />}
|
||||
>
|
||||
<Share className="h-4 w-4" />
|
||||
<TooltipTrigger asChild>
|
||||
<Button size="icon" variant="ghost">
|
||||
<Share className="h-4 w-4" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Share with others</p>
|
||||
@@ -620,11 +605,9 @@ function TooltipStory() {
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="username">Username</Label>
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Input id="username" placeholder="Enter username" />
|
||||
}
|
||||
/>
|
||||
<TooltipTrigger asChild>
|
||||
<Input id="username" placeholder="Enter username" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>
|
||||
<p>Must be 3-20 characters, letters and numbers only</p>
|
||||
</TooltipContent>
|
||||
@@ -633,7 +616,9 @@ function TooltipStory() {
|
||||
|
||||
<div className="flex items-center space-x-2">
|
||||
<Tooltip>
|
||||
<TooltipTrigger render={<Checkbox id="terms" />} />
|
||||
<TooltipTrigger asChild>
|
||||
<Checkbox id="terms" />
|
||||
</TooltipTrigger>
|
||||
<TooltipContent className="max-w-xs">
|
||||
<p>
|
||||
By checking this, you agree to our Terms of Service and
|
||||
@@ -766,7 +751,7 @@ function TooltipStory() {
|
||||
</li>
|
||||
<li>
|
||||
<strong>TooltipTrigger:</strong> Element that triggers the
|
||||
tooltip (use render prop)
|
||||
tooltip (use asChild prop)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -492,7 +492,7 @@ export const COMPONENTS_REGISTRY: ComponentInfo[] = [
|
||||
status: 'stable',
|
||||
component: CardButtonStory,
|
||||
sourceFile: '@kit/ui/card-button',
|
||||
props: ['className', 'children', 'onClick', 'disabled'],
|
||||
props: ['asChild', 'className', 'children', 'onClick', 'disabled'],
|
||||
icon: MousePointer,
|
||||
},
|
||||
|
||||
@@ -950,7 +950,7 @@ export const COMPONENTS_REGISTRY: ComponentInfo[] = [
|
||||
status: 'stable',
|
||||
component: ItemStory,
|
||||
sourceFile: '@kit/ui/item',
|
||||
props: ['variant', 'size', 'className'],
|
||||
props: ['variant', 'size', 'asChild', 'className'],
|
||||
icon: Layers,
|
||||
},
|
||||
|
||||
@@ -1004,7 +1004,7 @@ export const COMPONENTS_REGISTRY: ComponentInfo[] = [
|
||||
status: 'stable',
|
||||
component: BreadcrumbStory,
|
||||
sourceFile: '@kit/ui/breadcrumb',
|
||||
props: ['separator', 'href', 'className'],
|
||||
props: ['separator', 'asChild', 'href', 'className'],
|
||||
icon: ChevronRight,
|
||||
},
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { withI18n } from '../../lib/i18n/with-i18n';
|
||||
import { DocsContent } from './components/docs-content';
|
||||
import { DocsHeader } from './components/docs-header';
|
||||
import { DocsSidebar } from './components/docs-sidebar';
|
||||
@@ -28,4 +29,4 @@ async function ComponentDocsPage(props: ComponentDocsPageProps) {
|
||||
);
|
||||
}
|
||||
|
||||
export default ComponentDocsPage;
|
||||
export default withI18n(ComponentDocsPage);
|
||||
|
||||
@@ -67,10 +67,10 @@ export default async function EmailPage(props: EmailPageProps) {
|
||||
Remember that the below is an approximation of the email. Always test
|
||||
it in your inbox.{' '}
|
||||
<Dialog>
|
||||
<DialogTrigger
|
||||
render={<Button variant={'link'} className="p-0 underline" />}
|
||||
>
|
||||
Test Email
|
||||
<DialogTrigger asChild>
|
||||
<Button variant={'link'} className="p-0 underline">
|
||||
Test Email
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
|
||||
<DialogContent>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as z from 'zod';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const EmailTesterFormSchema = z.object({
|
||||
username: z.string().min(1),
|
||||
|
||||
@@ -49,16 +49,13 @@ export default async function EmailsPage() {
|
||||
|
||||
<div className={'grid grid-cols-1 gap-4 md:grid-cols-4'}>
|
||||
{categoryTemplates.map((template) => (
|
||||
<CardButton
|
||||
key={template.id}
|
||||
render={
|
||||
<Link href={`/emails/${template.id}`}>
|
||||
<CardButtonHeader>
|
||||
<CardButtonTitle>{template.name}</CardButtonTitle>
|
||||
</CardButtonHeader>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
<CardButton key={template.id} asChild>
|
||||
<Link href={`/emails/${template.id}`}>
|
||||
<CardButtonHeader>
|
||||
<CardButtonTitle>{template.name}</CardButtonTitle>
|
||||
</CardButtonHeader>
|
||||
</Link>
|
||||
</CardButton>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,6 @@ import type { Metadata } from 'next';
|
||||
|
||||
import { DevToolLayout } from '@/components/app-layout';
|
||||
import { RootProviders } from '@/components/root-providers';
|
||||
import { getMessages } from 'next-intl/server';
|
||||
|
||||
import '../styles/globals.css';
|
||||
|
||||
@@ -11,17 +10,15 @@ export const metadata: Metadata = {
|
||||
description: 'The dev tool for Makerkit',
|
||||
};
|
||||
|
||||
export default async function RootLayout({
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const messages = await getMessages();
|
||||
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
<RootProviders messages={messages}>
|
||||
<RootProviders>
|
||||
<DevToolLayout>{children}</DevToolLayout>
|
||||
</RootProviders>
|
||||
</body>
|
||||
|
||||
@@ -37,6 +37,7 @@ export default async function DashboardPage() {
|
||||
return (
|
||||
<Page style={'custom'}>
|
||||
<PageHeader
|
||||
displaySidebarTrigger={false}
|
||||
title={'Dev Tool'}
|
||||
description={'Kit MCP status for this workspace'}
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as z from 'zod';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const CreatePRDSchema = z.object({
|
||||
title: z
|
||||
@@ -32,4 +32,4 @@ export const CreatePRDSchema = z.object({
|
||||
.min(1, 'At least one success metric is required'),
|
||||
});
|
||||
|
||||
export type CreatePRDData = z.output<typeof CreatePRDSchema>;
|
||||
export type CreatePRDData = z.infer<typeof CreatePRDSchema>;
|
||||
|
||||
@@ -131,14 +131,12 @@ export function TranslationsComparison({
|
||||
|
||||
<If condition={locales.length > 1}>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button variant="outline" className="ml-auto">
|
||||
Select Languages
|
||||
<ChevronDownIcon className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="ml-auto">
|
||||
Select Languages
|
||||
<ChevronDownIcon className="ml-2 h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent align="end" className="w-[200px]">
|
||||
{locales.map((locale) => (
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { revalidatePath } from 'next/cache';
|
||||
|
||||
import * as z from 'zod';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { findWorkspaceRoot } from '@kit/mcp-server/env';
|
||||
import {
|
||||
|
||||
@@ -731,15 +731,13 @@ function FilterSwitcher(props: {
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger
|
||||
render={
|
||||
<Button variant="outline" className="font-normal">
|
||||
{buttonLabel()}
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" className="font-normal">
|
||||
{buttonLabel()}
|
||||
|
||||
<ChevronsUpDownIcon className="text-muted-foreground ml-1 h-3 w-3" />
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<ChevronsUpDownIcon className="text-muted-foreground ml-1 h-3 w-3" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuCheckboxItem
|
||||
@@ -888,41 +886,38 @@ function Summary({ appState }: { appState: AppEnvState }) {
|
||||
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
size={'sm'}
|
||||
onClick={() => {
|
||||
let data = '';
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="outline"
|
||||
size={'sm'}
|
||||
onClick={() => {
|
||||
let data = '';
|
||||
|
||||
const groups = getGroups(appState, () => true);
|
||||
const groups = getGroups(appState, () => true);
|
||||
|
||||
groups.forEach((group) => {
|
||||
data += `# ${group.category}\n`;
|
||||
groups.forEach((group) => {
|
||||
data += `# ${group.category}\n`;
|
||||
|
||||
group.variables.forEach((variable) => {
|
||||
data += `${variable.key}=${variable.effectiveValue}\n`;
|
||||
});
|
||||
|
||||
data += '\n';
|
||||
group.variables.forEach((variable) => {
|
||||
data += `${variable.key}=${variable.effectiveValue}\n`;
|
||||
});
|
||||
|
||||
const promise = copyToClipboard(data);
|
||||
data += '\n';
|
||||
});
|
||||
|
||||
toast.promise(promise, {
|
||||
loading: 'Copying environment variables...',
|
||||
success: 'Environment variables copied to clipboard.',
|
||||
error:
|
||||
'Failed to copy environment variables to clipboard',
|
||||
});
|
||||
}}
|
||||
>
|
||||
<CopyIcon className={'mr-2 h-4 w-4'} />
|
||||
<span>Copy env file to clipboard</span>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
const promise = copyToClipboard(data);
|
||||
|
||||
toast.promise(promise, {
|
||||
loading: 'Copying environment variables...',
|
||||
success: 'Environment variables copied to clipboard.',
|
||||
error: 'Failed to copy environment variables to clipboard',
|
||||
});
|
||||
}}
|
||||
>
|
||||
<CopyIcon className={'mr-2 h-4 w-4'} />
|
||||
<span>Copy env file to clipboard</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
|
||||
<TooltipContent>
|
||||
Copy environment variables to clipboard. You can place it in your
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { revalidatePath } from 'next/cache';
|
||||
|
||||
import * as z from 'zod';
|
||||
import { z } from 'zod';
|
||||
|
||||
import {
|
||||
createKitEnvDeps,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DevToolSidebar } from '@/components/app-sidebar';
|
||||
|
||||
import { SidebarInset, SidebarProvider } from '@kit/ui/sidebar';
|
||||
import { SidebarInset, SidebarProvider } from '@kit/ui/shadcn-sidebar';
|
||||
|
||||
export function DevToolLayout(props: React.PropsWithChildren) {
|
||||
return (
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
SidebarMenuSub,
|
||||
SidebarMenuSubButton,
|
||||
SidebarMenuSubItem,
|
||||
} from '@kit/ui/sidebar';
|
||||
} from '@kit/ui/shadcn-sidebar';
|
||||
import { isRouteActive } from '@kit/ui/utils';
|
||||
|
||||
const routes = [
|
||||
@@ -92,14 +92,14 @@ export function DevToolSidebar({
|
||||
{route.children.map((child) => (
|
||||
<SidebarMenuSubItem key={child.path}>
|
||||
<SidebarMenuSubButton
|
||||
render={
|
||||
<Link href={child.path}>
|
||||
<child.Icon className="h-4 w-4" />
|
||||
<span>{child.label}</span>
|
||||
</Link>
|
||||
}
|
||||
asChild
|
||||
isActive={isRouteActive(child.path, pathname, false)}
|
||||
/>
|
||||
>
|
||||
<Link href={child.path}>
|
||||
<child.Icon className="h-4 w-4" />
|
||||
<span>{child.label}</span>
|
||||
</Link>
|
||||
</SidebarMenuSubButton>
|
||||
</SidebarMenuSubItem>
|
||||
))}
|
||||
</SidebarMenuSub>
|
||||
@@ -107,13 +107,13 @@ export function DevToolSidebar({
|
||||
) : (
|
||||
<SidebarMenuButton
|
||||
isActive={isRouteActive(route.path, pathname, false)}
|
||||
render={
|
||||
<Link href={route.path}>
|
||||
<route.Icon className="h-4 w-4" />
|
||||
<span>{route.label}</span>
|
||||
</Link>
|
||||
}
|
||||
/>
|
||||
asChild
|
||||
>
|
||||
<Link href={route.path}>
|
||||
<route.Icon className="h-4 w-4" />
|
||||
<span>{route.label}</span>
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
)}
|
||||
</SidebarMenuItem>
|
||||
))}
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import type { AbstractIntlMessages } from 'next-intl';
|
||||
|
||||
import { I18nClientProvider } from '@kit/i18n/provider';
|
||||
import { I18nProvider } from '@kit/i18n/provider';
|
||||
import { Toaster } from '@kit/ui/sonner';
|
||||
|
||||
export function RootProviders(
|
||||
props: React.PropsWithChildren<{ messages: AbstractIntlMessages }>,
|
||||
) {
|
||||
import { i18nResolver } from '../lib/i18n/i18n.resolver';
|
||||
import { getI18nSettings } from '../lib/i18n/i18n.settings';
|
||||
|
||||
export function RootProviders(props: React.PropsWithChildren) {
|
||||
return (
|
||||
<I18nClientProvider locale="en" messages={props.messages}>
|
||||
<I18nProvider settings={getI18nSettings('en')} resolver={i18nResolver}>
|
||||
<ReactQueryProvider>{props.children}</ReactQueryProvider>
|
||||
</I18nClientProvider>
|
||||
</I18nProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ interface ServiceCardProps {
|
||||
export const ServiceCard = ({ name, status }: ServiceCardProps) => {
|
||||
return (
|
||||
<Card className="w-full max-w-2xl">
|
||||
<CardContent>
|
||||
<CardContent className="p-4">
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center space-x-4">
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { getRequestConfig } from 'next-intl/server';
|
||||
|
||||
import account from '../../web/i18n/messages/en/account.json';
|
||||
import auth from '../../web/i18n/messages/en/auth.json';
|
||||
import billing from '../../web/i18n/messages/en/billing.json';
|
||||
import common from '../../web/i18n/messages/en/common.json';
|
||||
import marketing from '../../web/i18n/messages/en/marketing.json';
|
||||
import teams from '../../web/i18n/messages/en/teams.json';
|
||||
|
||||
export default getRequestConfig(async () => {
|
||||
return {
|
||||
locale: 'en',
|
||||
messages: {
|
||||
common,
|
||||
auth,
|
||||
account,
|
||||
teams,
|
||||
billing,
|
||||
marketing,
|
||||
},
|
||||
timeZone: 'UTC',
|
||||
getMessageFallback(info) {
|
||||
return info.key;
|
||||
},
|
||||
};
|
||||
});
|
||||
13
apps/dev-tool/lib/i18n/with-i18n.tsx
Normal file
13
apps/dev-tool/lib/i18n/with-i18n.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { createI18nServerInstance } from './i18n.server';
|
||||
|
||||
type LayoutOrPageComponent<Params> = React.ComponentType<Params>;
|
||||
|
||||
export function withI18n<Params extends object>(
|
||||
Component: LayoutOrPageComponent<Params>,
|
||||
) {
|
||||
return async function I18nServerComponentWrapper(params: Params) {
|
||||
await createI18nServerInstance();
|
||||
|
||||
return <Component {...params} />;
|
||||
};
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
import type { NextConfig } from 'next';
|
||||
|
||||
import createNextIntlPlugin from 'next-intl/plugin';
|
||||
|
||||
const withNextIntl = createNextIntlPlugin('./i18n/request.ts');
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
reactStrictMode: true,
|
||||
transpilePackages: ['@kit/ui', '@kit/shared', '@kit/i18n'],
|
||||
transpilePackages: ['@kit/ui', '@kit/shared'],
|
||||
reactCompiler: true,
|
||||
devIndicators: {
|
||||
position: 'bottom-right',
|
||||
@@ -18,4 +14,4 @@ const nextConfig: NextConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
export default withNextIntl(nextConfig);
|
||||
export default nextConfig;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
"@tanstack/react-query": "catalog:",
|
||||
"lucide-react": "catalog:",
|
||||
"next": "catalog:",
|
||||
"next-intl": "catalog:",
|
||||
"nodemailer": "catalog:",
|
||||
"react": "catalog:",
|
||||
"react-dom": "catalog:",
|
||||
@@ -36,7 +35,7 @@
|
||||
"babel-plugin-react-compiler": "1.0.0",
|
||||
"pino-pretty": "13.0.0",
|
||||
"react-hook-form": "catalog:",
|
||||
"recharts": "3.7.0",
|
||||
"recharts": "2.15.3",
|
||||
"tailwindcss": "catalog:",
|
||||
"tw-animate-css": "catalog:",
|
||||
"typescript": "^5.9.3",
|
||||
|
||||
@@ -66,6 +66,26 @@
|
||||
--animate-accordion-down: accordion-down 0.2s ease-out;
|
||||
--animate-accordion-up: accordion-up 0.2s ease-out;
|
||||
|
||||
@keyframes accordion-down {
|
||||
from {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
height: var(--radix-accordion-content-height);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes accordion-up {
|
||||
from {
|
||||
height: var(--radix-accordion-content-height);
|
||||
}
|
||||
|
||||
to {
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-up {
|
||||
0% {
|
||||
opacity: 0;
|
||||
|
||||
Reference in New Issue
Block a user