Skip to content

Commit 83d8e48

Browse files
bteasxzz
andauthored
feat: add autoSave toggle button (#283)
Co-authored-by: 三咲智子 Kevin Deng <[email protected]>
1 parent 7467f38 commit 83d8e48

File tree

5 files changed

+45
-24
lines changed

5 files changed

+45
-24
lines changed

src/Repl.vue

+7-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export interface Props {
1717
editor: EditorComponentType
1818
store?: Store
1919
autoResize?: boolean
20-
autoSave?: boolean // auto save and compile, default to true, if false, user need to press ctrl + s to save and compile
2120
showCompileOutput?: boolean
2221
showImportMap?: boolean
2322
showTsConfig?: boolean
@@ -37,17 +36,18 @@ export interface Props {
3736
showRuntimeWarning?: boolean
3837
}
3938
editorOptions?: {
40-
showErrorText?: string
39+
showErrorText?: string | false
40+
autoSaveText?: string | false
4141
monacoOptions?: monaco.editor.IStandaloneEditorConstructionOptions
4242
}
4343
}
4444
45+
const autoSave = defineModel<boolean>({ default: true })
4546
const props = withDefaults(defineProps<Props>(), {
4647
theme: 'light',
4748
previewTheme: false,
4849
store: () => useStore(),
4950
autoResize: true,
50-
autoSave: true,
5151
showCompileOutput: true,
5252
showImportMap: true,
5353
showTsConfig: true,
@@ -70,7 +70,10 @@ props.store.init()
7070
const editorSlotName = computed(() => (props.layoutReverse ? 'right' : 'left'))
7171
const outputSlotName = computed(() => (props.layoutReverse ? 'left' : 'right'))
7272
73-
provide(injectKeyProps, toRefs(props))
73+
provide(injectKeyProps, {
74+
...toRefs(props),
75+
autoSave,
76+
})
7477
provide(
7578
injectKeyPreviewRef,
7679
computed(() => outputRef.value?.previewRef?.container ?? null),

src/editor/EditorContainer.vue

+29-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import FileSelector from './FileSelector.vue'
33
import Message from '../Message.vue'
44
import { debounce } from '../utils'
55
import { inject, ref, watch } from 'vue'
6-
import MessageToggle from './MessageToggle.vue'
6+
import ToggleButton from './ToggleButton.vue'
77
import { type EditorComponentType, injectKeyProps } from '../types'
88
99
const SHOW_ERROR_KEY = 'repl_show_error'
@@ -12,7 +12,7 @@ const props = defineProps<{
1212
editorComponent: EditorComponentType
1313
}>()
1414
15-
const { store } = inject(injectKeyProps)!
15+
const { store, autoSave, editorOptions } = inject(injectKeyProps)!
1616
const showMessage = ref(getItem())
1717
1818
const onChange = debounce((code: string) => {
@@ -42,7 +42,19 @@ watch(showMessage, () => {
4242
@change="onChange"
4343
/>
4444
<Message v-show="showMessage" :err="store.errors[0]" />
45-
<MessageToggle v-model="showMessage" />
45+
46+
<div class="editor-floating">
47+
<ToggleButton
48+
v-if="editorOptions?.showErrorText !== false"
49+
v-model="showMessage"
50+
:text="editorOptions?.showErrorText || 'Show Error'"
51+
/>
52+
<ToggleButton
53+
v-if="editorOptions?.autoSaveText !== false"
54+
v-model="autoSave"
55+
:text="editorOptions?.autoSaveText || 'Auto Save'"
56+
/>
57+
</div>
4658
</div>
4759
</template>
4860

@@ -52,4 +64,18 @@ watch(showMessage, () => {
5264
overflow: hidden;
5365
position: relative;
5466
}
67+
68+
.editor-floating {
69+
position: absolute;
70+
bottom: 16px;
71+
right: 16px;
72+
z-index: 11;
73+
display: flex;
74+
flex-direction: column;
75+
align-items: end;
76+
gap: 8px;
77+
background-color: var(--bg);
78+
color: var(--text-light);
79+
padding: 8px;
80+
}
5581
</style>

src/editor/MessageToggle.vue src/editor/ToggleButton.vue

+5-15
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
<script setup lang="ts">
2-
import { inject } from 'vue'
3-
import { injectKeyProps } from '../../src/types'
4-
5-
const { editorOptions } = inject(injectKeyProps)!
6-
const visible = defineModel<boolean>()
2+
defineProps<{ text: string }>()
3+
const active = defineModel<boolean>()
74
</script>
85

96
<template>
10-
<div class="wrapper" @click="visible = !visible">
11-
<span>{{ editorOptions?.showErrorText || 'Show Error' }}</span>
7+
<div class="wrapper" @click="active = !active">
8+
<span>{{ text }}</span>
129
<div class="toggle" :class="[{ active: modelValue }]">
1310
<div class="indicator" />
1411
</div>
@@ -17,19 +14,12 @@ const visible = defineModel<boolean>()
1714

1815
<style scoped>
1916
.wrapper {
20-
position: absolute;
21-
bottom: 8px;
22-
right: 15px;
23-
z-index: 11;
2417
display: flex;
2518
align-items: center;
26-
background-color: var(--bg);
27-
color: var(--text-light);
2819
cursor: pointer;
29-
padding: 4px 8px;
30-
border-radius: 2px;
3120
user-select: none;
3221
}
22+
3323
.toggle {
3424
display: inline-block;
3525
margin-left: 4px;

src/types.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ export type EditorComponentType = Component<EditorProps>
1515

1616
export type OutputModes = 'preview' | EditorMode
1717

18-
export const injectKeyProps: InjectionKey<ToRefs<Required<Props>>> =
19-
Symbol('props')
18+
export const injectKeyProps: InjectionKey<
19+
ToRefs<Required<Props & { autoSave: boolean }>>
20+
> = Symbol('props')
2021
export const injectKeyPreviewRef: InjectionKey<
2122
ComputedRef<HTMLDivElement | null>
2223
> = Symbol('preview-ref')

test/main.ts

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const App = {
6868
// showCompileOutput: false,
6969
// showImportMap: false
7070
editorOptions: {
71+
autoSaveText: '💾',
7172
monacoOptions: {
7273
// wordWrap: 'on',
7374
},

0 commit comments

Comments
 (0)