Skip to content

Commit

Permalink
feat: 增加 settings 页面和修改 menu 组件
Browse files Browse the repository at this point in the history
  • Loading branch information
Sparkle committed Jul 20, 2024
1 parent 38f8250 commit c20a15b
Show file tree
Hide file tree
Showing 9 changed files with 3,344 additions and 1,331 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"framer-motion": "10.17.9",
Expand Down
4,340 changes: 3,016 additions & 1,324 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/app/edit/(main)/(router)/plugins/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FC } from 'react';

const Plugins: FC = () => {
return <div className="p-4 h-full">Plugins</div>;
};

export default Plugins;
124 changes: 124 additions & 0 deletions src/app/edit/(main)/(router)/settings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { FC, ReactNode } from 'react';
import { PiWarningCircleBold, PiCodeThin } from 'react-icons/pi';
import { VscPreview } from 'react-icons/vsc';

import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { Menu, MenuItem } from '@/components/menu';

const Settings: FC = () => {
const titleStyle = 'my-2 font-bold';

return (
<div className="p-4 h-full">
<div>Settings</div>
<div>
<div className={titleStyle}>WEBCONTAINERS</div>
<div className="flex items-center text-sm text-gray-400 my-1">
<span className="mr-2">Compile trigger</span>
<TooltipProvider delayDuration={500}>
<Tooltip>
<TooltipTrigger>
<PiWarningCircleBold />
</TooltipTrigger>
<TooltipContent className="bg-gray-800 text-white" side={'right'}>
<p>Controls when edited files are synced tothe WebContainers filesystem.</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
<CompileSelector />
</div>
<div>
<div className={titleStyle}>EDITOR SETTINGS</div>
<EditorSettings />
</div>
</div>
);
};

const CompileSelector: FC = () => {
const selectOptions = [
{
text: 'Edit(auto)',
id: 0,
},
{
text: 'Save',
id: 1,
},
{
text: 'KeyStroke',
id: 2,
},
];

return (
<Select defaultValue="Edit(auto)">
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Theme" />
</SelectTrigger>
<SelectContent>
{selectOptions.map((option) => (
<SelectItem value={option.text} key={option.id}>
{option.text}
</SelectItem>
))}
</SelectContent>
</Select>
);
};

const EditorSettings: FC = () => {
interface settingOption {
text: string;
id: number;
icon: ReactNode;
}

const editorSettingOptions: Array<settingOption> = [
{
text: 'User settings',
id: 0,
icon: <VscPreview />,
},
{
text: 'Workspace settings',
id: 1,
icon: <VscPreview />,
},
{
text: 'User snippets',
id: 2,
icon: <PiCodeThin />,
},
{
text: 'Workspace snippets',
id: 3,
icon: <PiCodeThin />,
},
];

return (
<div>
<Menu>
{editorSettingOptions.map((option) => (
<MenuItem>
<div className="flex items-center">
<span className="mx-2">{option.icon}</span>
<span> {option.text}</span>
</div>
</MenuItem>
))}
</Menu>
</div>
);
};

export default Settings;
6 changes: 3 additions & 3 deletions src/components/avatarPopover/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from 'react-icons/ai';

import { Avatar } from '@/components/common/Avatar';
import { Menu, MenuItem } from '@/components/avatarPopover/menu';
import { Menu, MenuItem } from '@/components/menu';

const AvatarPopoverContent: FC = () => {
const menuItemTwStyle = `flex items-center`;
Expand All @@ -24,7 +24,7 @@ const AvatarPopoverContent: FC = () => {
<Avatar className="bg-slate-700 w-20 h-20 mt-5"></Avatar>
<span className="mt-5 text-white select-none">Your Name</span>
<span className="text-xs text-gray-200 select-none mb-5">Your Account</span>
<Menu>
<Menu topLine>
<MenuItem className={menuItemTwStyle} onClick={testHandle}>
<AiOutlineHome className="mx-2" />
Your dashboard
Expand All @@ -42,7 +42,7 @@ const AvatarPopoverContent: FC = () => {
Local projects
</MenuItem>
</Menu>
<Menu>
<Menu topLine>
<MenuItem className={menuItemTwStyle}>
<AiOutlinePoweroff className="mx-2" />
Sign out
Expand Down
4 changes: 2 additions & 2 deletions src/components/extension/tree-view-api/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,8 @@ const Folder = forwardRef<HTMLDivElement, FolderProps & React.HTMLAttributes<HTM
>
<div className=" flex items-center justify-start gap-x-1">
{expendedItems?.includes(value)
? (openIcon ?? <FolderOpenIcon className="h-3 w-3" />)
: (closeIcon ?? <FolderIcon className="h-3 w-3" />)}
? openIcon ?? <FolderOpenIcon className="h-3 w-3" />
: closeIcon ?? <FolderIcon className="h-3 w-3" />}
<span>{element}</span>
</div>
<RiDeleteBin6Line
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ const MenuItem: FC<{
);
};

const Menu: FC<{ children?: ReactNode; className?: string }> = ({ children, className }) => {
const Menu: FC<{
children?: ReactNode;
className?: string;
topLine?: boolean | undefined;
}> = ({ children, className, topLine = false }) => {
const defaultClassName = `relative w-full py-2 `;
const hasTopLine = topLine || (typeof topLine === 'undefined' && children);

return (
<div className={`${defaultClassName} ${className ?? ''}`}>
<div className="w-full h-[1px] bg-gray-600 absolute top-0 opacity-50"></div>
{hasTopLine && <div className="w-full h-[1px] bg-gray-600 absolute top-0 opacity-50"></div>}
{children}
</div>
);
Expand Down
153 changes: 153 additions & 0 deletions src/components/ui/select/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
'use client';

import * as React from 'react';
import * as SelectPrimitive from '@radix-ui/react-select';
import { Check, ChevronDown, ChevronUp } from 'lucide-react';

import { cn } from '@/utils';

const Select = SelectPrimitive.Root;

const SelectGroup = SelectPrimitive.Group;

const SelectValue = SelectPrimitive.Value;

const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
className,
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;

const SelectScrollUpButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollUpButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn('flex cursor-default items-center justify-center py-1', className)}
{...props}
>
<ChevronUp className="h-4 w-4" />
</SelectPrimitive.ScrollUpButton>
));
SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;

const SelectScrollDownButton = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.ScrollDownButton>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
>(({ className, ...props }, ref) => (
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn('flex cursor-default items-center justify-center py-1', className)}
{...props}
>
<ChevronDown className="h-4 w-4" />
</SelectPrimitive.ScrollDownButton>
));
SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;

const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, position = 'popper', ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
position === 'popper' &&
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
className,
)}
position={position}
{...props}
>
<SelectScrollUpButton />
<SelectPrimitive.Viewport
className={cn(
'p-1',
position === 'popper' &&
'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]',
)}
>
{children}
</SelectPrimitive.Viewport>
<SelectScrollDownButton />
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
SelectContent.displayName = SelectPrimitive.Content.displayName;

const SelectLabel = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Label>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Label
ref={ref}
className={cn('py-1.5 pl-8 pr-2 text-sm font-semibold', className)}
{...props}
/>
));
SelectLabel.displayName = SelectPrimitive.Label.displayName;

const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
className,
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>

<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = SelectPrimitive.Item.displayName;

const SelectSeparator = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
>(({ className, ...props }, ref) => (
<SelectPrimitive.Separator
ref={ref}
className={cn('-mx-1 my-1 h-px bg-muted', className)}
{...props}
/>
));
SelectSeparator.displayName = SelectPrimitive.Separator.displayName;

export {
Select,
SelectGroup,
SelectValue,
SelectTrigger,
SelectContent,
SelectLabel,
SelectItem,
SelectSeparator,
SelectScrollUpButton,
SelectScrollDownButton,
};
30 changes: 30 additions & 0 deletions src/components/ui/tooltip/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client';

import * as React from 'react';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';

import { cn } from '@/utils';

const TooltipProvider = TooltipPrimitive.Provider;

const Tooltip = TooltipPrimitive.Root;

const TooltipTrigger = TooltipPrimitive.Trigger;

const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
'z-50 overflow-hidden rounded-md bg-primary px-3 py-1.5 text-xs text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className,
)}
{...props}
/>
));
TooltipContent.displayName = TooltipPrimitive.Content.displayName;

export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };

0 comments on commit c20a15b

Please sign in to comment.