@varlet/cli 1.23.11 → 1.24.2-alpha.1640861757955

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/generators/base/package.json +2 -2
  3. package/lib/commands/changelog.d.ts +6 -0
  4. package/lib/commands/changelog.js +27 -0
  5. package/lib/commands/commitLint.d.ts +1 -0
  6. package/lib/commands/commitLint.js +21 -0
  7. package/lib/commands/compile.js +3 -3
  8. package/lib/commands/create.js +8 -8
  9. package/lib/commands/dev.js +2 -2
  10. package/lib/commands/gen.js +3 -3
  11. package/lib/commands/jest.js +1 -1
  12. package/lib/commands/release.d.ts +1 -0
  13. package/lib/commands/release.js +197 -0
  14. package/lib/compiler/compileSFC.js +5 -5
  15. package/lib/compiler/compileScript.js +19 -19
  16. package/lib/compiler/compileSiteEntry.js +7 -7
  17. package/lib/compiler/compileStyle.js +6 -6
  18. package/lib/compiler/compileTemplateHighlight.js +4 -4
  19. package/lib/compiler/compileTypes.js +5 -5
  20. package/lib/config/jest.config.js +3 -3
  21. package/lib/config/vite.config.js +5 -5
  22. package/lib/index.js +13 -2
  23. package/package.json +30 -37
  24. package/site/components/code-example/CodeExample.vue +107 -0
  25. package/site/components/code-example/codeExample.less +23 -0
  26. package/site/components/code-example/index.ts +10 -0
  27. package/site/components/icon/icon.less +1 -0
  28. package/site/components/loading/props.ts +2 -2
  29. package/site/components/snackbar/Snackbar.vue +38 -0
  30. package/site/components/snackbar/core.vue +117 -0
  31. package/site/components/snackbar/index.tsx +270 -0
  32. package/site/components/snackbar/props.ts +94 -0
  33. package/site/components/snackbar/snackbar.less +135 -0
  34. package/site/components/utils/elements.ts +8 -0
  35. package/site/components/utils/shared.ts +3 -0
  36. package/site/mobile/App.vue +6 -6
  37. package/site/module.d.ts +4 -0
  38. package/site/pc/App.vue +8 -10
  39. package/site/pc/components/AppHeader.vue +8 -9
  40. package/site/pc/components/AppSidebar.vue +6 -6
  41. package/site/pc/main.ts +8 -2
  42. package/site/tsconfig.json +1 -6
  43. package/site/useProgress.ts +6 -2
  44. package/site/utils.ts +4 -3
  45. package/tsconfig.json +0 -2
  46. package/varlet.default.config.js +13 -0
  47. package/generators/base/.gitignore +0 -14
  48. package/site/.DS_Store +0 -0
  49. package/site/components/.DS_Store +0 -0
@@ -0,0 +1,270 @@
1
+ import VarSiteSnackbarCore from './core.vue'
2
+ import VarSiteSnackbar from './Snackbar.vue'
3
+ import context from '../context'
4
+ import { reactive, TransitionGroup } from 'vue'
5
+ import { mountInstance } from '../utils/components'
6
+ import { isPlainObject, toNumber } from '../utils/shared'
7
+ import type { LoadingType, LoadingSize } from '../loading/props'
8
+ import type { App, Component, TeleportProps } from 'vue'
9
+
10
+ export type SnackbarType = 'success' | 'warning' | 'info' | 'error' | 'loading'
11
+
12
+ export const SNACKBAR_TYPE: Array<SnackbarType> = ['loading', 'success', 'warning', 'info', 'error']
13
+
14
+ interface SnackbarHandel {
15
+ clear: () => void
16
+ }
17
+
18
+ interface SnackbarOptions {
19
+ type?: SnackbarType
20
+ content?: string
21
+ position?: 'top' | 'center' | 'bottom'
22
+ loadingType?: LoadingType
23
+ loadingSize?: LoadingSize
24
+ lockScroll?: boolean
25
+ contentClass?: string
26
+ duration?: number
27
+ vertical?: boolean
28
+ show?: boolean
29
+ forbidClick?: boolean
30
+ onOpen?: () => void
31
+ onClose?: () => void
32
+ onOpened?: () => void
33
+ onClosed?: () => void
34
+ // internal
35
+ teleport?: TeleportProps['to']
36
+ }
37
+
38
+ interface UniqSnackbarOptions {
39
+ id: number
40
+ reactiveSnackOptions: SnackbarOptions
41
+ _update?: string
42
+ animationEnd?: boolean
43
+ }
44
+
45
+ interface Snackbar {
46
+ (options: SnackbarOptions | string): SnackbarHandel
47
+
48
+ install(app: App): void
49
+
50
+ allowMultiple(bool: boolean): void
51
+
52
+ success(options: SnackbarOptions | string): SnackbarHandel
53
+
54
+ warning(options: SnackbarOptions | string): SnackbarHandel
55
+
56
+ info(options: SnackbarOptions | string): SnackbarHandel
57
+
58
+ error(options: SnackbarOptions | string): SnackbarHandel
59
+
60
+ loading(options: SnackbarOptions | string): SnackbarHandel
61
+
62
+ clear(): void
63
+
64
+ Component: Component
65
+ }
66
+
67
+ let sid = 0
68
+ let isMount = false
69
+ let unmount: () => void
70
+ let isAllowMultiple = false
71
+ let uniqSnackbarOptions: Array<UniqSnackbarOptions> = reactive<UniqSnackbarOptions[]>([])
72
+
73
+ const defaultOption: Partial<Record<keyof SnackbarOptions, any>> = {
74
+ type: undefined,
75
+ content: '',
76
+ position: 'top',
77
+ duration: 3000,
78
+ vertical: false,
79
+ contentClass: undefined,
80
+ loadingType: 'circle',
81
+ loadingSize: 'normal',
82
+ lockScroll: false,
83
+ teleport: 'body',
84
+ forbidClick: false,
85
+ onOpen: () => {},
86
+ onOpened: () => {},
87
+ onClose: () => {},
88
+ onClosed: () => {},
89
+ }
90
+
91
+ const transitionGroupProps: any = {
92
+ name: 'var-site-snackbar-fade',
93
+ tag: 'div',
94
+ class: 'var-site-transition-group',
95
+ }
96
+
97
+ const TransitionGroupHost = {
98
+ setup: function() {
99
+ return () => {
100
+ const snackbarList = uniqSnackbarOptions.map(({ id, reactiveSnackOptions, _update }: UniqSnackbarOptions) => {
101
+ const transitionGroupEl = document.querySelector('.var-site-transition-group')
102
+ if (reactiveSnackOptions.forbidClick || reactiveSnackOptions.type === 'loading') {
103
+ ;(transitionGroupEl as HTMLElement).classList.add('var-site-pointer-auto')
104
+ } else {
105
+ ;(transitionGroupEl as HTMLElement).classList.remove('var-site-pointer-auto')
106
+ }
107
+
108
+ if (isAllowMultiple) reactiveSnackOptions.position = 'top'
109
+
110
+ const position = isAllowMultiple ? 'relative' : 'absolute' // avoid stylelint value-keyword-case error
111
+
112
+ const style = {
113
+ position,
114
+ ...getTop(reactiveSnackOptions.position)
115
+ }
116
+
117
+ return (
118
+ <VarSiteSnackbarCore
119
+ {...reactiveSnackOptions}
120
+ key={id}
121
+ style={style}
122
+ data-id={id}
123
+ _update={_update}
124
+ v-model={[reactiveSnackOptions.show, 'show']}
125
+ />
126
+ )
127
+ })
128
+
129
+ const zindex = context.zIndex // avoid stylelint value-keyword-case error
130
+
131
+ return (
132
+ <TransitionGroup
133
+ {...transitionGroupProps}
134
+ style={{ zIndex: zindex }}
135
+ onAfterEnter={opened}
136
+ onAfterLeave={removeUniqOption}
137
+ >
138
+ {snackbarList}
139
+ </TransitionGroup>
140
+ )
141
+ }
142
+ }
143
+ }
144
+
145
+ const Snackbar: Snackbar = function (options: SnackbarOptions | string): SnackbarHandel {
146
+ const snackOptions: SnackbarOptions = isPlainObject(options) ? options : { content: options }
147
+ const reactiveSnackOptions: SnackbarOptions = reactive<SnackbarOptions>({
148
+ ...defaultOption,
149
+ ...snackOptions,
150
+ })
151
+ reactiveSnackOptions.show = true
152
+
153
+ if (!isMount) {
154
+ isMount = true
155
+ unmount = mountInstance(TransitionGroupHost).unmountInstance
156
+ }
157
+
158
+ const { length } = uniqSnackbarOptions
159
+ const uniqSnackbarOptionItem: UniqSnackbarOptions = {
160
+ id: sid++,
161
+ reactiveSnackOptions,
162
+ }
163
+
164
+ if (length === 0 || isAllowMultiple) {
165
+ addUniqOption(uniqSnackbarOptionItem)
166
+ } else {
167
+ const _update = `update-${sid}`
168
+ updateUniqOption(reactiveSnackOptions, _update)
169
+ }
170
+
171
+ return {
172
+ clear() {
173
+ if (!isAllowMultiple && uniqSnackbarOptions.length) {
174
+ uniqSnackbarOptions[0].reactiveSnackOptions.show = false
175
+ } else {
176
+ reactiveSnackOptions.show = false
177
+ }
178
+ },
179
+ }
180
+ } as Snackbar
181
+
182
+ SNACKBAR_TYPE.forEach((type) => {
183
+ Snackbar[type] = (options: SnackbarOptions | string): SnackbarHandel => {
184
+ if (isPlainObject(options)) {
185
+ options.type = type
186
+ } else {
187
+ options = {
188
+ content: options,
189
+ type,
190
+ }
191
+ }
192
+ return Snackbar(options)
193
+ }
194
+ })
195
+
196
+ Snackbar.install = function (app: App) {
197
+ app.component(VarSiteSnackbar.name, VarSiteSnackbar)
198
+ }
199
+
200
+ Snackbar.allowMultiple = function (bool = false) {
201
+ if (bool !== isAllowMultiple) {
202
+ uniqSnackbarOptions.forEach((option: UniqSnackbarOptions) => {
203
+ option.reactiveSnackOptions.show = false
204
+ })
205
+
206
+ isAllowMultiple = bool
207
+ }
208
+ }
209
+
210
+ Snackbar.clear = function () {
211
+ uniqSnackbarOptions.forEach((option: UniqSnackbarOptions) => {
212
+ option.reactiveSnackOptions.show = false
213
+ })
214
+ }
215
+
216
+ Snackbar.Component = VarSiteSnackbar
217
+
218
+ function opened(element: HTMLElement): void {
219
+ const id = element.getAttribute('data-id')
220
+ const option = uniqSnackbarOptions.find((option) => option.id === toNumber(id))
221
+ if (option) option.reactiveSnackOptions.onOpened?.()
222
+ }
223
+
224
+ function removeUniqOption(element: HTMLElement): void {
225
+ element.parentElement && element.parentElement.classList.remove('var-site-pointer-auto')
226
+ const id = element.getAttribute('data-id')
227
+
228
+ const option = uniqSnackbarOptions.find((option) => option.id === toNumber(id))
229
+ if (option) {
230
+ option.animationEnd = true
231
+ option.reactiveSnackOptions.onClosed?.()
232
+ }
233
+
234
+ const isAllAnimationEnd = uniqSnackbarOptions.every((option) => option.animationEnd)
235
+
236
+ if (isAllAnimationEnd) {
237
+ unmount?.()
238
+ uniqSnackbarOptions = reactive<UniqSnackbarOptions[]>([])
239
+ isMount = false
240
+ }
241
+ }
242
+
243
+ function addUniqOption(uniqSnackbarOptionItem: UniqSnackbarOptions) {
244
+ uniqSnackbarOptions.push(uniqSnackbarOptionItem)
245
+ }
246
+
247
+ function updateUniqOption(reactiveSnackOptions: SnackbarOptions, _update: string) {
248
+ const [firstOption] = uniqSnackbarOptions
249
+
250
+ firstOption.reactiveSnackOptions = {
251
+ ...firstOption.reactiveSnackOptions,
252
+ ...reactiveSnackOptions,
253
+ }
254
+
255
+ firstOption._update = _update
256
+ }
257
+
258
+ function getTop(position = 'top') {
259
+ if (position === 'bottom') return { [position]: '5%' }
260
+
261
+ return { top: position === 'top' ? '5%' : '45%' }
262
+ }
263
+
264
+ VarSiteSnackbar.install = function (app: App) {
265
+ app.component(VarSiteSnackbar.name, VarSiteSnackbar)
266
+ }
267
+
268
+ export const _SnackbarComponent = VarSiteSnackbar
269
+
270
+ export default Snackbar
@@ -0,0 +1,94 @@
1
+ import { pickProps } from '../utils/components'
2
+ import { props as loadingProps } from '../loading/props'
3
+ import { SNACKBAR_TYPE, SnackbarType } from './index'
4
+ import type { PropType, TeleportProps } from 'vue'
5
+
6
+ export function positionValidator(position: string): boolean {
7
+ const validPositions = ['top', 'center', 'bottom']
8
+ return validPositions.includes(position)
9
+ }
10
+
11
+ export function typeValidator(type: SnackbarType): boolean {
12
+ return SNACKBAR_TYPE.includes(type)
13
+ }
14
+
15
+ export const props = {
16
+ type: {
17
+ type: String as PropType<SnackbarType>,
18
+ validator: typeValidator,
19
+ },
20
+ // snackbar显示的位置
21
+ position: {
22
+ type: String,
23
+ default: 'top',
24
+ validator: positionValidator,
25
+ },
26
+ // content内容
27
+ content: {
28
+ type: String,
29
+ },
30
+ // 为snackbar content添加自定义类名
31
+ contentClass: {
32
+ type: String,
33
+ },
34
+ // snackbar 持续时间
35
+ duration: {
36
+ type: Number,
37
+ default: 3000,
38
+ },
39
+ // 是否将消息条内容堆叠在操作(按钮)之上
40
+ vertical: {
41
+ type: Boolean,
42
+ default: false,
43
+ },
44
+ // 加载动画类型
45
+ loadingType: pickProps(loadingProps, 'type'),
46
+ // 加载动画尺寸
47
+ loadingSize: pickProps(loadingProps, 'size'),
48
+ // 是否禁止滚动穿透
49
+ lockScroll: {
50
+ type: Boolean,
51
+ default: false,
52
+ },
53
+ // 控制组件可见还是隐藏
54
+ show: {
55
+ type: Boolean,
56
+ default: false,
57
+ },
58
+ // teleport
59
+ teleport: {
60
+ type: String as PropType<TeleportProps['to']>,
61
+ default: 'body',
62
+ },
63
+ // 是否禁止点击背景
64
+ forbidClick: {
65
+ type: Boolean,
66
+ default: false,
67
+ },
68
+ // 打开时的回调函数
69
+ onOpen: {
70
+ type: Function,
71
+ default: () => {},
72
+ },
73
+ // 打开动画结束时的回调
74
+ onOpened: {
75
+ type: Function,
76
+ default: () => {},
77
+ },
78
+ // 关闭时的回调函数
79
+ onClose: {
80
+ type: Function,
81
+ default: () => {},
82
+ },
83
+ // 关闭动画结束时的回调
84
+ onClosed: {
85
+ type: Function,
86
+ default: () => {},
87
+ },
88
+ 'onUpdate:show': {
89
+ type: Function,
90
+ },
91
+ _update: {
92
+ type: String,
93
+ },
94
+ }
@@ -0,0 +1,135 @@
1
+ @site-snackbar-width: 256px;
2
+ @site-snackbar-color: rgba(255, 255, 255, 0.87);
3
+ @site-snackbar-border-radius: 4px;
4
+ @site-snackbar-background: #333;
5
+ @site-snackbar-font-size: var(--site-font-size-md);
6
+ @site-snackbar-margin: 6px 24px;
7
+ @site-snackbar-border-color: currentColor;
8
+ @site-snackbar-success-background: var(--site-color-success);
9
+ @site-snackbar-info-background: var(--site-color-info);
10
+ @site-snackbar-error-background: var(--site-color-danger);
11
+ @site-snackbar-warning-background: var(--site-color-warning);
12
+ @site-snackbar-content-padding: 14px 16px;
13
+ @site-snackbar-action-margin: 0 16px 0 0;
14
+
15
+ :root {
16
+ --site-snackbar-width: @site-snackbar-width;
17
+ --site-snackbar-color: @site-snackbar-color;
18
+ --site-snackbar-border-radius: @site-snackbar-border-radius;
19
+ --site-snackbar-background: @site-snackbar-background;
20
+ --site-snackbar-font-size: @site-snackbar-font-size;
21
+ --site-snackbar-margin: @site-snackbar-margin;
22
+ --site-snackbar-border-color: @site-snackbar-border-color;
23
+ --site-snackbar-success-background: @site-snackbar-success-background;
24
+ --site-snackbar-info-background: @site-snackbar-info-background;
25
+ --site-snackbar-error-background: @site-snackbar-error-background;
26
+ --site-snackbar-warning-background: @site-snackbar-warning-background;
27
+ --site-snackbar-content-padding: @site-snackbar-content-padding;
28
+ --site-snackbar-action-margin: @site-snackbar-action-margin;
29
+ }
30
+
31
+ .var-site-transition-group {
32
+ position: fixed;
33
+ left: 0;
34
+ right: 0;
35
+ top: 0;
36
+ bottom: 0;
37
+ pointer-events: none;
38
+ }
39
+
40
+ .var-site-pointer-auto {
41
+ pointer-events: auto;
42
+ }
43
+
44
+ .var-site {
45
+ &-snackbar {
46
+ display: flex;
47
+ justify-content: center;
48
+ align-items: baseline;
49
+ left: 0;
50
+ right: 0;
51
+ bottom: 0;
52
+ transition: all 0.15s var(--site-cubic-bezier);
53
+
54
+ &__wrapper {
55
+ width: var(--site-snackbar-width);
56
+ display: flex;
57
+ border-radius: var(--site-snackbar-border-radius);
58
+ color: var(--site-snackbar-color);
59
+ background: var(--site-snackbar-background);
60
+ font-size: var(--site-snackbar-font-size);
61
+ margin: var(--site-snackbar-margin);
62
+ align-items: center;
63
+ border-color: var(--site-snackbar-border-color);
64
+ pointer-events: auto;
65
+ transition: 0.3s var(--site-cubic-bezier);
66
+
67
+ &-success {
68
+ background: var(--site-snackbar-success-background);
69
+ }
70
+
71
+ &-info {
72
+ background: var(--site-snackbar-info-background);
73
+ }
74
+
75
+ &-warning {
76
+ background: var(--site-snackbar-warning-background);
77
+ }
78
+
79
+ &-error {
80
+ background: var(--site-snackbar-error-background);
81
+ }
82
+ }
83
+
84
+ &__content {
85
+ flex-grow: 1;
86
+ padding: var(--site-snackbar-content-padding);
87
+ }
88
+
89
+ &__action {
90
+ margin: var(--site-snackbar-action-margin);
91
+ display: flex;
92
+ }
93
+
94
+ &__vertical {
95
+ flex-direction: column;
96
+ align-items: flex-start;
97
+
98
+ .var-site-snackbar__action {
99
+ align-self: flex-end;
100
+ margin-bottom: 8px;
101
+ }
102
+ }
103
+
104
+ &-fade-leave-active {
105
+ position: absolute;
106
+ }
107
+
108
+ &-fade-enter-from,
109
+ &-fade-leave-to {
110
+ opacity: 0;
111
+ transform: translateY(-30px);
112
+ }
113
+ }
114
+
115
+ &-snackbar-transition {
116
+ top: 0;
117
+ position: fixed;
118
+
119
+ .var-site-snackbar__wrapper {
120
+ position: absolute;
121
+
122
+ &-top {
123
+ top: 5%;
124
+ }
125
+
126
+ &-center {
127
+ top: 45%;
128
+ }
129
+
130
+ &-bottom {
131
+ bottom: 5%;
132
+ }
133
+ }
134
+ }
135
+ }
@@ -81,3 +81,11 @@ export function formatStyleVars(styleVars: StyleVars | null) {
81
81
  return styles
82
82
  }, {} as StyleVars)
83
83
  }
84
+
85
+ export function doubleRaf() {
86
+ return new Promise((resolve) => {
87
+ requestAnimationFrame(() => {
88
+ requestAnimationFrame(resolve)
89
+ })
90
+ })
91
+ }
@@ -12,6 +12,9 @@ export const toNumber = (val: number | string | boolean | undefined | null): num
12
12
  return val
13
13
  }
14
14
 
15
+ export const isPlainObject = (val: unknown): val is Record<string, any> =>
16
+ Object.prototype.toString.call(val) === '[object Object]'
17
+
15
18
  export function kebabCase(str: string): string {
16
19
  const reg = /([^-])([A-Z])/g
17
20
 
@@ -86,7 +86,6 @@
86
86
  </template>
87
87
 
88
88
  <script lang="ts">
89
- // @ts-ignore
90
89
  import config from '@config'
91
90
  import { computed, ComputedRef, defineComponent, ref, Ref, watch } from 'vue'
92
91
  import { useRoute } from 'vue-router'
@@ -98,7 +97,7 @@ import {
98
97
  removeEmpty,
99
98
  setThemes,
100
99
  watchLang,
101
- watchThemes
100
+ watchThemes,
102
101
  } from '../utils'
103
102
  import { get } from 'lodash-es'
104
103
 
@@ -112,11 +111,12 @@ export default defineComponent({
112
111
  const languages: Ref<Record<string, string>> = ref(get(config, 'mobile.header.i18n'))
113
112
  const nonEmptyLanguages: ComputedRef<Record<string, string>> = computed(() => removeEmpty(languages.value))
114
113
  const redirect = get(config, 'mobile.redirect', '')
114
+ const themesKey = get(config, 'themesKey')
115
115
  const github: Ref<string> = ref(get(config, 'mobile.header.github'))
116
116
  const darkMode: Ref<string> = ref(get(config, 'mobile.header.darkMode'))
117
- const currentThemes = ref(getBrowserThemes())
117
+ const currentThemes = ref(getBrowserThemes(themesKey))
118
118
 
119
- const changeLanguage = (lang) => {
119
+ const changeLanguage = (lang: string) => {
120
120
  language.value = lang
121
121
  showMenu.value = false
122
122
  window.location.href = `./mobile.html#${route.path}?language=${language.value}&replace=${route.query.replace}`
@@ -136,7 +136,7 @@ export default defineComponent({
136
136
 
137
137
  const toGithub = () => {
138
138
  if (inIframe() && !isPhone()) {
139
- window.top.open(github.value)
139
+ window.top!.open(github.value)
140
140
  } else {
141
141
  window.location.href = github.value
142
142
  }
@@ -161,7 +161,7 @@ export default defineComponent({
161
161
  const setCurrentThemes = (themes: 'themes' | 'darkThemes') => {
162
162
  currentThemes.value = themes
163
163
  setThemes(config, currentThemes.value)
164
- window.localStorage.setItem('currentThemes', currentThemes.value)
164
+ window.localStorage.setItem(themesKey, currentThemes.value)
165
165
  }
166
166
 
167
167
  const toggleTheme = () => {
@@ -0,0 +1,4 @@
1
+ declare module 'clipboard'
2
+ declare module '@pc-routes'
3
+ declare module '@mobile-routes'
4
+ declare module '@config'
package/site/pc/App.vue CHANGED
@@ -29,11 +29,10 @@
29
29
  </template>
30
30
 
31
31
  <script lang="ts">
32
- // @ts-ignore
33
32
  import config from '@config'
34
- import AppMobile from './components/AppMobile'
35
- import AppHeader from './components/AppHeader'
36
- import AppSidebar from './components/AppSidebar'
33
+ import AppMobile from './components/AppMobile.vue'
34
+ import AppHeader from './components/AppHeader.vue'
35
+ import AppSidebar from './components/AppSidebar.vue'
37
36
  import { defineComponent, nextTick, onMounted, ref, Ref, watch } from 'vue'
38
37
  import { useRoute } from 'vue-router'
39
38
  import { get } from 'lodash-es'
@@ -52,7 +51,6 @@ export default defineComponent({
52
51
  AppSidebar
53
52
  },
54
53
  setup() {
55
- // config
56
54
  const defaultLanguage = get(config, 'defaultLanguage')
57
55
  const menu: Ref<Menu[]> = ref(get(config, 'pc.menu', []))
58
56
  const useMobile = ref(get(config, 'useMobile'))
@@ -79,7 +77,7 @@ export default defineComponent({
79
77
 
80
78
  nextTick(() => {
81
79
  const children = document
82
- .querySelector('.varlet-site-sidebar')
80
+ .querySelector('.varlet-site-sidebar')!
83
81
  .getElementsByClassName('var-site-cell')
84
82
  const index = menu.value.findIndex((item) => item.doc === menuName)
85
83
 
@@ -93,7 +91,7 @@ export default defineComponent({
93
91
  }
94
92
 
95
93
  const handleSidebarChange = (menu: Menu) => {
96
- doc.value.scrollTop = 0
94
+ doc.value!.scrollTop = 0
97
95
  componentName.value = getComponentNameByMenuName(menu.doc)
98
96
  menuName.value = menu.doc
99
97
  }
@@ -287,17 +285,17 @@ iframe {
287
285
  }
288
286
 
289
287
  pre {
290
- margin: 20px 0 0;
288
+ margin: 10px 0 0;
291
289
  }
292
290
 
293
291
  code {
294
292
  position: relative;
295
293
  display: block;
296
- padding: 16px;
294
+ padding: 10px 16px;
297
295
  overflow-x: auto;
298
296
  font-size: 13px;
299
297
  font-family: Consolas, Monaco, monospace;
300
- line-height: 26px;
298
+ line-height: 31px;
301
299
  white-space: pre-wrap;
302
300
  word-wrap: break-word;
303
301
  color: #fff;
@@ -61,15 +61,14 @@
61
61
  </template>
62
62
 
63
63
  <script lang="ts">
64
- // @ts-ignore
65
64
  import config from '@config'
66
- import { ref, computed } from 'vue'
65
+ import { ref, computed, defineComponent } from 'vue'
67
66
  import { get } from 'lodash-es'
68
67
  import { getBrowserThemes, getPCLocationInfo, removeEmpty, setThemes, watchThemes } from '../../utils'
69
68
  import { useRouter } from 'vue-router'
70
69
  import type { Ref, ComputedRef } from 'vue'
71
70
 
72
- export default {
71
+ export default defineComponent({
73
72
  name: 'AppHeader',
74
73
  props: {
75
74
  language: {
@@ -77,19 +76,19 @@ export default {
77
76
  },
78
77
  },
79
78
  setup() {
80
- // config
81
79
  const title: Ref<string> = ref(get(config, 'title'))
82
80
  const logo: Ref<string> = ref(get(config, 'logo'))
81
+ const themesKey = get(config, 'themesKey')
83
82
  const languages: Ref<Record<string, string>> = ref(get(config, 'pc.header.i18n'))
84
83
  const github: Ref<Record<string, string>> = ref(get(config, 'pc.header.github'))
85
84
  const darkMode: Ref<Record<string, string>> = ref(get(config, 'pc.header.darkMode'))
86
- const currentThemes = ref(getBrowserThemes())
85
+ const currentThemes = ref(getBrowserThemes(themesKey))
87
86
 
88
87
  const isOpenMenu: Ref<boolean> = ref(false)
89
88
  const router = useRouter()
90
89
  const nonEmptyLanguages: ComputedRef<Record<string, string>> = computed(() => removeEmpty(languages.value))
91
90
 
92
- const handleLanguageChange = (language) => {
91
+ const handleLanguageChange = (language: string) => {
93
92
  const { menuName } = getPCLocationInfo()
94
93
  router.replace(`/${language}/${menuName}`)
95
94
  isOpenMenu.value = false
@@ -98,7 +97,7 @@ export default {
98
97
  const setCurrentThemes = (themes: 'themes' | 'darkThemes') => {
99
98
  currentThemes.value = themes
100
99
  setThemes(config, currentThemes.value)
101
- window.localStorage.setItem('currentThemes', currentThemes.value)
100
+ window.localStorage.setItem(themesKey, currentThemes.value)
102
101
  }
103
102
 
104
103
  const getThemesMessage = () => ({ action: 'themesChange', from: 'pc', data: currentThemes.value })
@@ -106,7 +105,7 @@ export default {
106
105
  const toggleTheme = () => {
107
106
  setCurrentThemes(currentThemes.value === 'darkThemes' ? 'themes' : 'darkThemes')
108
107
  window.postMessage(getThemesMessage(), '*')
109
- ;(document.getElementById('mobile') as HTMLIFrameElement).contentWindow.postMessage(getThemesMessage(), '*')
108
+ ;(document.getElementById('mobile') as HTMLIFrameElement).contentWindow!.postMessage(getThemesMessage(), '*')
110
109
  }
111
110
 
112
111
  watchThemes((themes, from) => {
@@ -129,7 +128,7 @@ export default {
129
128
  toggleTheme,
130
129
  }
131
130
  },
132
- }
131
+ })
133
132
  </script>
134
133
 
135
134
  <style scoped lang="less">