diff --git a/src/app/edit/layout.tsx b/src/app/edit/layout.tsx index 7e6604a..d011ee1 100644 --- a/src/app/edit/layout.tsx +++ b/src/app/edit/layout.tsx @@ -97,8 +97,7 @@ const Page: React.FC<{ children: React.ReactNode }> = ({ children }) => { const mathModel = models.filter((model) => model.id === file.id); if (mathModel.length > 0) { - mathModel[0].model && - setActiveModel(mathModel[0].filename, mathModel[0].model, willChangeEditorId); + mathModel[0].model && setActiveModel(mathModel[0].id, mathModel[0], willChangeEditorId); mathModel[0].model && setModels( { filename: mathModel[0].filename, value: '', language: 'typescript', id: file.id }, diff --git a/src/components/edit/tabItem/index.tsx b/src/components/edit/tabItem/index.tsx index 74b7ed3..a1cd366 100644 --- a/src/components/edit/tabItem/index.tsx +++ b/src/components/edit/tabItem/index.tsx @@ -11,7 +11,7 @@ interface TabProps { filename: string; active: boolean; editorId: number; - setActiveModel: (filename: string, model: any, editorId: number) => void; + setActiveModel: (id: string, model: any, editorId: number) => void; editor: any; model: editor.ITextModel; removeModel: (filename: string, editorId: number) => any; diff --git a/src/components/editor/index.tsx b/src/components/editor/index.tsx index eec706b..97a24a7 100644 --- a/src/components/editor/index.tsx +++ b/src/components/editor/index.tsx @@ -3,6 +3,7 @@ import { useCallback } from 'react'; import Editor, { Monaco, loader } from '@monaco-editor/react'; import * as monaco from 'monaco-editor'; +import { editor } from 'monaco-editor'; import { useDroppable } from '@dnd-kit/core'; import { @@ -10,6 +11,7 @@ import { useMonacoStore, useActiveModelStore, useActiveEditorStore, + useModelsStore, } from '@/store/editorStore'; import { TabBar } from '@/components/edit/tabbar'; @@ -20,8 +22,9 @@ interface CodeEditorProps { export default function CodeEditor({ editorId }: CodeEditorProps) { const { getEditor, setEditor } = useEditorStore(); const { setMonaco } = useMonacoStore(); - const { activeMap } = useActiveModelStore(); - const { setActiveEditor } = useActiveEditorStore(); + const { setModels } = useModelsStore(); + const { activeMap, setActiveModel } = useActiveModelStore(); + const { activeEditorId, setActiveEditor } = useActiveEditorStore(); const thisEditor = getEditor(editorId); const currentModel = activeMap[editorId]; // console.log(thisEditor); @@ -55,6 +58,19 @@ export default function CodeEditor({ editorId }: CodeEditorProps) { setEditor(editorId, editor); setMonaco(editorId, monaco); + if (editorId !== 0) { + const newModel = activeEditorId < 1 ? activeMap[0] : activeMap[1]; + newModel.model && setActiveModel(newModel.modelId, newModel.model, editorId); + newModel.model && + setModels( + { filename: newModel.modelId, value: '', language: 'typescript', id: newModel.modelId }, + newModel.model.model, + editorId, + newModel.modelId, + ); + editor.setModel(newModel.model?.model as editor.ITextModel); + } + monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({ noSemanticValidation: false, noSyntaxValidation: false, diff --git a/src/components/file/fileItem/index.tsx b/src/components/file/fileItem/index.tsx index 7c8db80..d0ab522 100644 --- a/src/components/file/fileItem/index.tsx +++ b/src/components/file/fileItem/index.tsx @@ -74,7 +74,7 @@ export const FileItem: React.FC = ({ file, onMouseupFn }: FileIte // console.log(splitState, mathModel[0], willChangeEditor, willChangeEditorId); if (mathModel.length > 0) { - mathModel[0].model && setActiveModel(mathModel[0].id, mathModel[0].model, willChangeEditorId); + mathModel[0].model && setActiveModel(mathModel[0].id, mathModel[0], willChangeEditorId); mathModel[0].model && setModels( { filename: mathModel[0].filename, value: '', language: 'typescript', id: file.id }, @@ -126,7 +126,7 @@ export const FileItem: React.FC = ({ file, onMouseupFn }: FileIte const newModels = removeModel(file.id, editorId); if (newModels && newModels.filename) { - setActiveModel(newModels.filename, newModels.model, editorId); + setActiveModel(newModels.id, newModels.model, editorId); editor && editor.setModel(newModels.model); } else { removeAllModel(editorId); diff --git a/src/components/ui/avatar/index.stories.tsx b/src/components/ui/avatar/index.stories.tsx new file mode 100644 index 0000000..1bdac7c --- /dev/null +++ b/src/components/ui/avatar/index.stories.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; + +import { Avatar, AvatarImage, AvatarFallback } from './index'; + +export default { + title: 'Components/Avatar', + component: Avatar, + subcomponents: { AvatarImage, AvatarFallback }, +} as Meta; + +type AvatarProps = { + src: string; + alt: string; + fallback: string; +}; + +const Template: StoryFn = (args) => ( + + + {args.fallback} + +); + +export const Default = Template.bind({}); +Default.args = { + src: 'https://via.placeholder.com/150', + alt: 'Avatar Image', + fallback: 'AB', +}; + +export const WithFallback = Template.bind({}); +WithFallback.args = { + src: '', + alt: 'Avatar Image', + fallback: 'AB', +}; diff --git a/src/components/ui/badge/index.stories.tsx b/src/components/ui/badge/index.stories.tsx new file mode 100644 index 0000000..bd908ff --- /dev/null +++ b/src/components/ui/badge/index.stories.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; + +import { Badge, BadgeProps } from './index'; + +export default { + title: 'Components/Badge', + component: Badge, +} as Meta; + +const Template: StoryFn = (args) => ; + +export const Default = Template.bind({}); +Default.args = { + children: 'Default Badge', + variant: 'default', +}; + +export const Secondary = Template.bind({}); +Secondary.args = { + children: 'Secondary Badge', + variant: 'secondary', +}; + +export const Destructive = Template.bind({}); +Destructive.args = { + children: 'Destructive Badge', + variant: 'destructive', +}; + +export const Outline = Template.bind({}); +Outline.args = { + children: 'Outline Badge', + variant: 'outline', +}; diff --git a/src/components/ui/button/index.stories.tsx b/src/components/ui/button/index.stories.tsx new file mode 100644 index 0000000..6207beb --- /dev/null +++ b/src/components/ui/button/index.stories.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; + +import { Button, ButtonProps } from './index'; + +export default { + title: 'Components/Button', + component: Button, +} as Meta; + +const Template: StoryFn = (args) => + + + + Dialog Title + This is the dialog description + +
Dialog Content
+ + + + + + + Close + +
+ +); + +export const Default = Template.bind({}); +Default.args = {}; diff --git a/src/components/ui/dropdown-menu/index.stories.tsx b/src/components/ui/dropdown-menu/index.stories.tsx new file mode 100644 index 0000000..06d4201 --- /dev/null +++ b/src/components/ui/dropdown-menu/index.stories.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; + +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} from './index'; + +export default { + title: 'Components/DropdownMenu', + component: DropdownMenu, + subcomponents: { + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, + }, +} as Meta; + +const Template: StoryFn = (args) => ( + + + + + + Menu + Item 1 + Item 2 + + Checkbox Item + + Radio Item 1 + Radio Item 2 + + + Sub Menu + + Sub Item 1 + Sub Item 2 + + + + + Item with Shortcut + ⌘S + + + +); + +export const Default = Template.bind({}); +Default.args = {}; diff --git a/src/components/ui/input/index.stories.tsx b/src/components/ui/input/index.stories.tsx new file mode 100644 index 0000000..18ef79d --- /dev/null +++ b/src/components/ui/input/index.stories.tsx @@ -0,0 +1,30 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; + +import { Input, InputProps } from './index'; + +export default { + title: 'Components/Input', + component: Input, +} as Meta; + +const Template: StoryFn = (args) => ; + +export const Default = Template.bind({}); +Default.args = { + type: 'text', + placeholder: 'Enter text...', +}; + +export const Disabled = Template.bind({}); +Disabled.args = { + type: 'text', + placeholder: 'Disabled input...', + disabled: true, +}; + +export const WithDefaultValue = Template.bind({}); +WithDefaultValue.args = { + type: 'text', + defaultValue: 'Default value', +}; diff --git a/src/components/ui/scroll-area/index.stories.tsx b/src/components/ui/scroll-area/index.stories.tsx new file mode 100644 index 0000000..6ba68d0 --- /dev/null +++ b/src/components/ui/scroll-area/index.stories.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { Meta, StoryFn } from '@storybook/react'; + +import { ScrollArea, ScrollBar } from './index'; + +export default { + title: 'Components/ScrollArea', + component: ScrollArea, + subcomponents: { ScrollBar }, +} as Meta; + +const Template: StoryFn = (args) => ( +
+ +
+ This is a scrollable content area. Add more content here to see the scrollbars in action. +
+
+
+); + +export const Default = Template.bind({}); +Default.args = {}; diff --git a/src/store/editorStore.tsx b/src/store/editorStore.tsx index 028a446..6141da9 100644 --- a/src/store/editorStore.tsx +++ b/src/store/editorStore.tsx @@ -191,17 +191,17 @@ export const useModelsStore = create((set, get) => ( // modelId原为model对应文件名,为满足打开多个同名文件修改为对应文件的uuid interface activeModelState { - activeMap: { modelId: string; model: editor.ITextModel | null }[]; + activeMap: { modelId: string; model: modelType | null }[]; } interface activeModelAction { - setActiveModel: (modelId: string, model: editor.ITextModel, editorId: number) => void; + setActiveModel: (modelId: string, model: modelType, editorId: number) => void; clearActiveModel: (editorId: number) => void; } export const useActiveModelStore = create((set) => ({ activeMap: [], - setActiveModel: (modelId: string, model: editor.ITextModel, editorId: number) => + setActiveModel: (modelId: string, model: modelType, editorId: number) => set((state) => { const preActiveMap = [...state.activeMap]; preActiveMap[editorId] = { modelId, model }; diff --git a/src/utils/editor.ts b/src/utils/editor.ts index 4c7d9ec..b48007d 100644 --- a/src/utils/editor.ts +++ b/src/utils/editor.ts @@ -1,6 +1,6 @@ import monacoForType, { editor } from 'monaco-editor'; -import { modelInfoType } from '@/store/editorStore'; +import { modelInfoType, modelType } from '@/store/editorStore'; export function setModelsFromInfo( modelsInfo: modelInfoType[], @@ -12,7 +12,7 @@ export function setModelsFromInfo( editorId: number, id: string, ) => void, - setActiveModel: (modelId: string, model: editor.ITextModel, editorId: number) => void, + setActiveModel: (modelId: string, model: modelType, editorId: number) => void, editorId: number, ) { modelsInfo.forEach((modelInfo) => { @@ -30,7 +30,7 @@ export function addNewModel( editorId: number, id: string, ) => void, - setActiveModel: (modelId: string, model: editor.ITextModel, editorId: number) => void, + setActiveModel: (modelId: string, model: modelType, editorId: number) => void, editorId: number, ) { const modelUri = monaco.Uri.file(modelInfo.id); @@ -38,7 +38,9 @@ export function addNewModel( monaco.editor.getModel(modelUri) || monaco.editor.createModel(modelInfo.value, modelInfo.language, modelUri); // console.log(monaco.editor.getModel(modelUri)); - setActiveModel(modelInfo.id, model, editorId); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + setActiveModel(modelInfo.id, { ...modelInfo, model }, editorId); setModels(modelInfo, model, editorId, modelInfo.id); editor.setModel(model); }