[Feature] Add fullscreen.
diff --git a/studio/components/monaco/index.tsx b/studio/components/monaco/index.tsx
index 482708f..23ded2a 100644
--- a/studio/components/monaco/index.tsx
+++ b/studio/components/monaco/index.tsx
@@ -19,7 +19,6 @@
 import * as monaco from 'monaco-editor'
 import { useFormItem } from 'naive-ui/es/_mixins'
 import { call } from 'naive-ui/es/_utils'
-import { useLogHeight } from '@/hooks'
 import type {
   MaybeArray,
   OnUpdateValue,
@@ -43,6 +42,9 @@
       readOnly: false,
       language: 'shell'
     })
+  },
+  height: {
+    type: String
   }
 }
 
@@ -54,7 +56,6 @@
     const editorRef = ref()
     let editor = null as monaco.editor.IStandaloneCodeEditor | null
     const formItem = useFormItem({})
-    const { getEditorHeight, getLogHeight } = useLogHeight()
 
     const initMonacoEditor = () => {
       const dom = editorRef.value
@@ -92,7 +93,7 @@
       <div
         ref={editorRef}
         style={{
-          height: `${getEditorHeight() - getLogHeight() - 40 - 45}px`,
+          height: props.height,
           width: '100%',
           border: '1px solid #eee'
         }}
diff --git a/studio/components/tab/fullscreen.tsx b/studio/components/tab/fullscreen.tsx
new file mode 100644
index 0000000..8fee7f6
--- /dev/null
+++ b/studio/components/tab/fullscreen.tsx
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { defineComponent, renderSlot } from 'vue'
+import { NSpace, NButton, NCard } from 'naive-ui'
+import { useLocale } from '@/hooks'
+
+const Fullscreen = defineComponent({
+  name: 'fullscreen',
+  props: {
+    isFullscreen: {
+      type: Boolean
+    },
+    id: {
+      type: String
+    }
+  },
+  emits: ['close'],
+  setup(props, { slots, emit }) {
+    const { t } = useLocale()
+    const onClose = () => {
+      emit('close')
+    }
+    return () => (
+      <div id={props.id}>
+        {props.isFullscreen ? (
+          <NCard style={{ height: '100vh' }}>
+            <NSpace vertical>
+              {renderSlot(slots, 'default')}
+              <NSpace justify='end'>
+                <NButton size='small' type='primary' onClick={onClose}>
+                  {t('close')}
+                </NButton>
+              </NSpace>
+            </NSpace>
+          </NCard>
+        ) : (
+          renderSlot(slots, 'default')
+        )}
+      </div>
+    )
+  }
+})
+
+export default Fullscreen
diff --git a/studio/components/tab/index.tsx b/studio/components/tab/index.tsx
index ba40851..e0d664e 100644
--- a/studio/components/tab/index.tsx
+++ b/studio/components/tab/index.tsx
@@ -25,16 +25,19 @@
 import { useWebSocketStore } from '@/store/websocket'
 import { saveFile } from '@/service/modules/file'
 import { useLocale, useLogHeight } from '@/hooks'
+import Fullscreen from './fullscreen'
+import { useFullscreen } from './use-fullscreen'
 
 export const Tabs = defineComponent({
   name: 'tabs',
   setup() {
     const { t } = useLocale()
-
     const dialog = useDialog()
     const fileStore = useFileStore()
-    const { setCurrentLogHeight } = useLogHeight()
+    const { setCurrentLogHeight, getEditorHeight, getLogHeight } =
+      useLogHeight()
     const webSocketStore = useWebSocketStore()
+    const { isFullscreen, toggleFullscreen } = useFullscreen()
 
     const updateContent = (value: number) => {
       fileStore.changeTab(value)
@@ -86,6 +89,10 @@
       updateContent(value)
     }
 
+    const handleFullscreen = (id: number) => {
+      toggleFullscreen('file-editor-' + id)
+    }
+
     return () => (
       <NTabs
         value={fileStore.getCurrentFile.id}
@@ -111,11 +118,22 @@
                 </div>
               )}
             >
-              <Toolbar />
-              <MonacoEditor
-                v-model:value={file.content}
-                options={{ language }}
-              />
+              <Toolbar onFullscreen={() => void handleFullscreen(file.id)} />
+              <Fullscreen
+                id={'file-editor-' + file.id}
+                isFullscreen={isFullscreen.value}
+                onClose={() => void handleFullscreen(file.id)}
+              >
+                <MonacoEditor
+                  v-model:value={file.content}
+                  options={{ language }}
+                  height={
+                    !isFullscreen.value
+                      ? `${getEditorHeight() - getLogHeight() - 40 - 45}px`
+                      : 'calc(100vh - 70px)'
+                  }
+                />
+              </Fullscreen>
               <Log v-model:value={file.log} />
             </NTabPane>
           )
diff --git a/studio/components/tab/use-fullscreen.ts b/studio/components/tab/use-fullscreen.ts
new file mode 100644
index 0000000..db30b81
--- /dev/null
+++ b/studio/components/tab/use-fullscreen.ts
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { ref, onMounted, onUnmounted } from 'vue'
+import screenfull from 'screenfull'
+
+export function useFullscreen() {
+  const isFullscreen = ref(false)
+
+  const toggleFullscreen = (idSelector: string) => {
+    const Ele = document.getElementById(idSelector)
+    if (Ele) screenfull.toggle(Ele)
+  }
+
+  onMounted(() => {
+    screenfull.on(
+      'change',
+      () => void (isFullscreen.value = screenfull.isFullscreen)
+    )
+  })
+
+  onUnmounted(() => {
+    screenfull.on(
+      'change',
+      () => void (isFullscreen.value = screenfull.isFullscreen)
+    )
+  })
+
+  return {
+    isFullscreen,
+    toggleFullscreen
+  }
+}
diff --git a/studio/components/toolbar/index.tsx b/studio/components/toolbar/index.tsx
index 6bffe32..151ad56 100644
--- a/studio/components/toolbar/index.tsx
+++ b/studio/components/toolbar/index.tsx
@@ -32,7 +32,8 @@
 
 export const Toolbar = defineComponent({
   name: 'toolbar',
-  setup() {
+  emits: ['fullscreen'],
+  setup(props, { emit }) {
     const { t } = useLocale()
 
     const fileStore = useFileStore()
@@ -66,6 +67,10 @@
       stopFile(file.id)
     }
 
+    const handleFullscreen = () => {
+      emit('fullscreen')
+    }
+
     return () => (
       <div class={styles.toolbar}>
         <div class={styles.operate}>
@@ -105,7 +110,7 @@
           </NTooltip>
         </div>
         <div class={styles.operate}>
-          <NButton text style={{ fontSize: '18px' }}>
+          <NButton text style={{ fontSize: '18px' }} onClick={handleFullscreen}>
             <NIcon>
               <FullscreenOutlined />
             </NIcon>
diff --git a/studio/locales/en_US.ts b/studio/locales/en_US.ts
index 69536aa..80970ea 100644
--- a/studio/locales/en_US.ts
+++ b/studio/locales/en_US.ts
@@ -32,7 +32,8 @@
   force_close: 'Force close',
   cannel: 'Cannel',
   confirm: 'Confirm',
-  run_log: 'Run Log'
+  run_log: 'Run Log',
+  close: 'Close'
 }
 
 export type Locale = typeof enUS
diff --git a/studio/locales/zh_CN.ts b/studio/locales/zh_CN.ts
index 8c356e3..f4de580 100644
--- a/studio/locales/zh_CN.ts
+++ b/studio/locales/zh_CN.ts
@@ -32,5 +32,6 @@
   force_close: '强制关闭',
   cannel: '取消',
   confirm: '确认',
-  run_log: '运行日志'
+  run_log: '运行日志',
+  close: '关闭'
 }