@varlet/cli 1.27.8-alpha.1651665460392 → 1.27.8

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.
@@ -0,0 +1,396 @@
1
+ <script lang="ts">
2
+ import config from '@config'
3
+ import AppMobile from './components/AppMobile.vue'
4
+ import AppHeader from './components/AppHeader.vue'
5
+ import AppSidebar from './components/AppSidebar.vue'
6
+ import { defineComponent, nextTick, onMounted, ref, watch } from 'vue'
7
+ import { useRoute } from 'vue-router'
8
+ import { get } from 'lodash-es'
9
+ import { getPCLocationInfo, MenuTypes } from '../utils'
10
+ import type { Ref } from 'vue'
11
+
12
+ export interface Menu {
13
+ doc: string
14
+ text: Record<string, string>
15
+ type: MenuTypes
16
+ }
17
+
18
+ export default defineComponent({
19
+ components: {
20
+ AppMobile,
21
+ AppHeader,
22
+ AppSidebar
23
+ },
24
+ setup() {
25
+ const menu: Ref<Menu[]> = ref(get(config, 'pc.menu', []))
26
+ const useMobile = ref(get(config, 'useMobile'))
27
+ const mobileRedirect = get(config, 'mobile.redirect')
28
+
29
+ const language: Ref<string> = ref('')
30
+ const componentName: Ref<null | string> = ref(null)
31
+ const menuName: Ref<string> = ref('')
32
+ const doc: Ref<HTMLElement | null> = ref(null)
33
+ const route = useRoute()
34
+
35
+ const getComponentNameByMenuName = (menuName: string) => {
36
+ const currentMenu = menu.value.find(menu => menu.doc === menuName)
37
+ return currentMenu?.type === MenuTypes.COMPONENT ? menuName : mobileRedirect.slice(1)
38
+ }
39
+
40
+ const init = () => {
41
+ const { menuName } = getPCLocationInfo()
42
+
43
+ nextTick(() => {
44
+ const children = document
45
+ .querySelector('.varlet-site-sidebar')!
46
+ .getElementsByClassName('var-site-cell')
47
+ const index = menu.value.findIndex((item) => item.doc === menuName)
48
+
49
+ if (index !== -1) {
50
+ children[index].scrollIntoView({
51
+ block: 'center',
52
+ inline: 'start',
53
+ })
54
+ }
55
+ })
56
+ }
57
+
58
+ const handleSidebarChange = (menu: Menu) => {
59
+ doc.value!.scrollTop = 0
60
+ componentName.value = getComponentNameByMenuName(menu.doc)
61
+ menuName.value = menu.doc
62
+ }
63
+
64
+ onMounted(init)
65
+
66
+ watch(
67
+ () => route.path,
68
+ () => {
69
+ const { language: lang, menuName: _menuName } = getPCLocationInfo()
70
+ if (!lang || !_menuName) {
71
+ return
72
+ }
73
+
74
+ componentName.value = getComponentNameByMenuName(_menuName)
75
+ menuName.value = _menuName
76
+ language.value = lang
77
+ document.title = get(config, 'pc.title')[lang] as string
78
+ },
79
+ { immediate: true }
80
+ )
81
+
82
+ return {
83
+ menu,
84
+ language,
85
+ componentName,
86
+ menuName,
87
+ doc,
88
+ useMobile,
89
+ handleSidebarChange,
90
+ }
91
+ },
92
+ })
93
+ </script>
94
+
95
+ <template>
96
+ <div class="varlet-site">
97
+ <app-header :language="language" />
98
+
99
+ <div class="varlet-site-content">
100
+ <app-sidebar
101
+ :language="language"
102
+ :menu="menu"
103
+ :menu-name="menuName"
104
+ @change="handleSidebarChange"
105
+ />
106
+
107
+ <div
108
+ class="varlet-site-doc-container"
109
+ ref="doc"
110
+ :class="[!useMobile && 'varlet-site-doc-container--pc-only']"
111
+ >
112
+ <router-view />
113
+ </div>
114
+
115
+ <app-mobile
116
+ :component-name="componentName"
117
+ :language="language"
118
+ :replace="menuName"
119
+ v-show="useMobile"
120
+ />
121
+ </div>
122
+ </div>
123
+ </template>
124
+
125
+ <style>
126
+ .hljs {
127
+ background: var(--site-config-color-hl-background) !important;
128
+ padding: 0 !important;
129
+ transition: all .25s
130
+ }
131
+
132
+ .hljs code {
133
+ line-height: 31px;
134
+ }
135
+
136
+ .hljs-comment, .hljs-meta, .hljs-quote {
137
+ color: var(--site-config-color-hl-group-a)
138
+ }
139
+
140
+ .hljs-keyword, .hljs-name, .hljs-selector-tag, .hljs-tag {
141
+ color: var(--site-config-color-hl-group-b)
142
+ }
143
+
144
+ .hljs-attribute, .hljs-selector-id {
145
+ color: var(--site-config-color-hl-group-c)
146
+ }
147
+
148
+ .hljs-addition, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-string {
149
+ color: var(--site-config-color-hl-group-d)
150
+ }
151
+
152
+ .hljs-subst {
153
+ color: var(--site-config-color-hl-group-e)
154
+ }
155
+
156
+ .hljs-link, .hljs-regexp {
157
+ color: var(--site-config-color-hl-group-f)
158
+ }
159
+
160
+ .hljs-doctag, .hljs-section, .hljs-title, .hljs-type {
161
+ color: var(--site-config-color-hl-group-g)
162
+ }
163
+
164
+ .hljs-bullet, .hljs-literal, .hljs-symbol, .hljs-template-variable, .hljs-variable {
165
+ color: var(--site-config-color-hl-group-h)
166
+ }
167
+
168
+ .hljs-deletion, .hljs-number {
169
+ color: var(--site-config-color-hl-group-i)
170
+ }
171
+ </style>
172
+
173
+ <style lang="less">
174
+ @doc-active: {
175
+ display: inline;
176
+ font-family: inherit;
177
+ padding: 0;
178
+ white-space: pre-wrap;
179
+ }
180
+
181
+ * {
182
+ transition: background-color .25s, box-shadow .25s;
183
+ }
184
+
185
+ iframe {
186
+ display: block;
187
+ width: 100%;
188
+ height: 100%;
189
+ border: none;
190
+ }
191
+
192
+ .varlet {
193
+ &-introduce {
194
+ display: flex;
195
+ flex-direction: column;
196
+ align-items: center;
197
+ margin: 20px 0;
198
+ padding: 90px 40px;
199
+ border-top: 6px solid var(--site-config-color-introduce-border);
200
+ border-radius: 2px;
201
+ background: var(--site-config-color-bar);
202
+ box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
203
+
204
+ &__row {
205
+ display: flex;
206
+ align-items: center;
207
+ }
208
+
209
+ &__image {
210
+ width: 60px;
211
+ margin-right: 20px;
212
+ }
213
+
214
+ &__name {
215
+ font-size: 60px;
216
+ }
217
+
218
+ &__des {
219
+ color: var(--site-config-color-sub-text);
220
+ font-size: 16px;
221
+ margin-top: 16px;
222
+ -webkit-font-smoothing: antialiased;
223
+ }
224
+ }
225
+
226
+ &-component-preview {
227
+ margin-top: 20px;
228
+ }
229
+
230
+ &-site {
231
+ min-width: 1200px;
232
+ padding: 60px 0 0;
233
+ &-content {
234
+ display: flex;
235
+ background: var(--site-config-color-body);
236
+ margin-left: 240px;
237
+ min-height: calc(100vh - 60px);
238
+ }
239
+
240
+ &-doc-container {
241
+ flex: 1 0 0;
242
+ min-width: 500px;
243
+ padding: 0 25px;
244
+ overflow-x: hidden;
245
+
246
+ &::-webkit-scrollbar {
247
+ display: none;
248
+ }
249
+
250
+ &--pc-only {
251
+ padding: 0 90px 0 30px;
252
+ }
253
+ }
254
+
255
+ &-doc {
256
+ a {
257
+ color: var(--site-config-color-link);
258
+ -webkit-font-smoothing: antialiased;
259
+ word-break: keep-all;
260
+ font-size: 15px;
261
+ @doc-active();
262
+
263
+ &:hover {
264
+ opacity: 0.8;
265
+ }
266
+ }
267
+
268
+ h1,
269
+ h2,
270
+ h3,
271
+ h4,
272
+ h5,
273
+ h6 {
274
+ position: relative;
275
+ color: var(--site-config-color-text);
276
+ font-weight: normal;
277
+ line-height: 1.5;
278
+ }
279
+
280
+ h1 {
281
+ line-height: 40px;
282
+ font-size: 30px;
283
+ cursor: default;
284
+ }
285
+
286
+ h2 {
287
+ margin: 30px 0 20px;
288
+ font-size: 25px;
289
+ }
290
+
291
+ h3 {
292
+ font-size: 18px;
293
+ margin: 0;
294
+ }
295
+
296
+ h4 {
297
+ margin: 18px 0 0;
298
+ }
299
+
300
+ p,
301
+ ul,
302
+ ol {
303
+ -webkit-font-smoothing: antialiased;
304
+ color: var(--site-config-color-text);
305
+ font-size: 15px;
306
+ line-height: 26px;
307
+ border-radius: 4px;
308
+ background: var(--site-config-color-bar);
309
+ list-style: none;
310
+ margin: 14px 0 0;
311
+ padding: 0;
312
+ }
313
+
314
+ pre {
315
+ margin: 0;
316
+ }
317
+
318
+ code {
319
+ position: relative;
320
+ display: block;
321
+ padding: 10px 16px;
322
+ overflow-x: auto;
323
+ font-size: 13px;
324
+ font-family: Consolas, Monaco, monospace;
325
+ white-space: pre-wrap;
326
+ word-wrap: break-word;
327
+ color: var(--site-config-color-hl-code);
328
+ }
329
+
330
+ p code,
331
+ li code,
332
+ table code {
333
+ -webkit-font-smoothing: antialiased;
334
+ word-break: keep-all;
335
+ color: var(--site-config-color-primary);
336
+ font-size: 15px;
337
+ @doc-active();
338
+ }
339
+
340
+ table {
341
+ -webkit-font-smoothing: antialiased;
342
+ width: 100%;
343
+ margin-top: 12px;
344
+ color: var(--site-config-color-text);
345
+ background: var(--site-config-color-bar);
346
+ font-size: 14px;
347
+ line-height: 28px;
348
+ border-collapse: collapse;
349
+ border-radius: 4px;
350
+
351
+ th {
352
+ padding: 8px 16px;
353
+ font-weight: 500;
354
+ text-align: left;
355
+ color: var(--site-config-color-sub-text);
356
+ font-size: 13px;
357
+ -webkit-font-smoothing: antialiased;
358
+ border-bottom: 1px solid var(--site-config-color-border);
359
+ }
360
+
361
+ td {
362
+ padding: 8px 16px;
363
+ border-bottom: 1px solid var(--site-config-color-border);
364
+ color: var(--site-config-color-text);
365
+ font-family: Consolas, Monaco, monospace;
366
+
367
+ code {
368
+ white-space: pre-wrap;
369
+ padding: 0;
370
+ font-size: 13px;
371
+ }
372
+ }
373
+
374
+ em {
375
+ color: var(--site-config-color-type);
376
+ font-style: normal;
377
+ -webkit-font-smoothing: antialiased;
378
+ font-size: 13px;
379
+ @doc-active();
380
+ }
381
+ }
382
+
383
+ .card {
384
+ border-radius: 4px;
385
+ background: var(--site-config-color-bar);
386
+ padding: 20px;
387
+ margin-bottom: 30px;
388
+ box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
389
+ &:first-child{
390
+ margin-top: 30px;
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ </style>
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import { defineComponent, onMounted, onBeforeUnmount, ref, useAttrs } from 'vue'
3
+ import { animationBoxData, animationEl, animationElClientRect } from '../floating'
4
+
5
+ export default defineComponent({
6
+ name: 'AnimationBox',
7
+ setup() {
8
+ const mutationObserver = ref<MutationObserver>()
9
+ const varletLogoAnimationRef = ref<HTMLElement>()
10
+ animationBoxData.attrs = useAttrs()
11
+
12
+ onMounted(() => {
13
+ animationEl.value = varletLogoAnimationRef.value
14
+ animationElClientRect.value = varletLogoAnimationRef?.value?.getBoundingClientRect();
15
+ mutationObserver.value = new MutationObserver(() => {
16
+ animationElClientRect.value = varletLogoAnimationRef?.value?.getBoundingClientRect();
17
+ });
18
+ mutationObserver.value.observe(document.body, { attributes: true, subtree: true, childList:true });
19
+ })
20
+
21
+ onBeforeUnmount(() => {
22
+ mutationObserver.value?.disconnect();
23
+ })
24
+
25
+ return {
26
+ varletLogoAnimationRef,
27
+ }
28
+ },
29
+ })
30
+ </script>
31
+
32
+ <template>
33
+ <div ref="varletLogoAnimationRef" data-animation="port"></div>
34
+ </template>
35
+
@@ -1,35 +1,18 @@
1
1
  <template>
2
2
  <div class="varlet-site-header">
3
- <div class="varlet-site-header__lead">
4
- <img class="varlet-site-header__logo" :src="logo" alt="logo" v-if="logo" />
3
+ <div class="varlet-site-header__lead" @click="backRoot">
4
+ <animation-box class="varlet-site-header__logo" />
5
5
  <div class="varlet-site-header__title" v-if="title">{{ title }}</div>
6
6
  </div>
7
7
 
8
8
  <div class="varlet-site-header__tail">
9
- <a
10
- class="varlet-site-header__link"
11
- target="_blank"
12
- :href="playground"
13
- v-ripple
14
- v-if="playground"
15
- >
9
+ <a class="varlet-site-header__link" target="_blank" :href="playground" v-ripple v-if="playground">
16
10
  <var-site-icon name="code-json" :size="24" />
17
11
  </a>
18
- <a
19
- class="varlet-site-header__link"
20
- target="_blank"
21
- :href="github"
22
- v-ripple
23
- v-if="github"
24
- >
12
+ <a class="varlet-site-header__link" target="_blank" :href="github" v-ripple v-if="github">
25
13
  <var-site-icon name="github" :size="28" />
26
14
  </a>
27
- <div
28
- class="varlet-site-header__theme"
29
- v-ripple
30
- v-if="darkMode"
31
- @click="toggleTheme"
32
- >
15
+ <div class="varlet-site-header__theme" v-ripple v-if="darkMode" @click="toggleTheme">
33
16
  <var-site-icon
34
17
  size="26px"
35
18
  :name="currentThemes === 'themes' ? 'white-balance-sunny' : 'weather-night'"
@@ -59,8 +42,7 @@
59
42
  :key="key"
60
43
  :class="{ 'varlet-site-header__language-list--active': language === key }"
61
44
  @click="handleLanguageChange(key)"
62
- >
63
- {{ value }}
45
+ >{{ value }}
64
46
  </var-site-cell>
65
47
  </div>
66
48
  </transition>
@@ -75,10 +57,12 @@ import { ref, computed, defineComponent } from 'vue'
75
57
  import { get } from 'lodash-es'
76
58
  import { getBrowserThemes, getPCLocationInfo, removeEmpty, setThemes, watchThemes } from '../../utils'
77
59
  import { useRouter } from 'vue-router'
60
+ import AnimationBox from './AnimationBox.vue'
78
61
  import type { Ref, ComputedRef } from 'vue'
79
62
 
80
63
  export default defineComponent({
81
64
  name: 'AppHeader',
65
+ components: { AnimationBox },
82
66
  props: {
83
67
  language: {
84
68
  type: String,
@@ -91,6 +75,7 @@ export default defineComponent({
91
75
  const languages: Ref<Record<string, string>> = ref(get(config, 'pc.header.i18n'))
92
76
  const playground: Ref<string> = ref(get(config, 'pc.header.playground'))
93
77
  const github: Ref<string> = ref(get(config, 'pc.header.github'))
78
+ const redirect = get(config, 'pc.redirect')
94
79
  const darkMode: Ref<boolean> = ref(get(config, 'pc.header.darkMode'))
95
80
  const currentThemes = ref(getBrowserThemes(themesKey))
96
81
 
@@ -98,6 +83,11 @@ export default defineComponent({
98
83
  const router = useRouter()
99
84
  const nonEmptyLanguages: ComputedRef<Record<string, string>> = computed(() => removeEmpty(languages.value))
100
85
 
86
+ const backRoot = () => {
87
+ const { language: lang } = getPCLocationInfo()
88
+ router.replace(`/${lang}${redirect}`)
89
+ }
90
+
101
91
  const handleLanguageChange = (language: string) => {
102
92
  const { menuName } = getPCLocationInfo()
103
93
  router.replace(`/${language}/${menuName}`)
@@ -135,6 +125,7 @@ export default defineComponent({
135
125
  isOpenMenu,
136
126
  darkMode,
137
127
  currentThemes,
128
+ backRoot,
138
129
  handleLanguageChange,
139
130
  toggleTheme,
140
131
  }
@@ -186,7 +177,7 @@ export default defineComponent({
186
177
  padding: 0 30px;
187
178
  justify-content: space-between;
188
179
  user-select: none;
189
- z-index: 996;
180
+ z-index: 9;
190
181
  background: var(--site-config-color-bar);
191
182
  border-bottom: 1px solid var(--site-config-color-border);
192
183
  box-sizing: border-box;
@@ -194,12 +185,15 @@ export default defineComponent({
194
185
  &__lead {
195
186
  display: flex;
196
187
  align-items: center;
188
+ cursor: pointer;
197
189
  }
198
190
 
199
191
  &__logo {
200
192
  width: 32px;
193
+ height: 32px;
201
194
  margin-right: 12px;
202
195
  flex-shrink: 0;
196
+ transition: 0.3s all ease-in-out;
203
197
  }
204
198
 
205
199
  &__title {
@@ -28,7 +28,7 @@ import config from '@config'
28
28
  import { MenuTypes } from '../../utils'
29
29
  import { reactive, ref, defineComponent } from 'vue'
30
30
  import type { PropType } from 'vue'
31
- import type { Menu } from '../App.vue'
31
+ import type { Menu } from '../Layout.vue'
32
32
  import { get } from 'lodash-es'
33
33
 
34
34
  export default defineComponent({
@@ -74,7 +74,7 @@ export default defineComponent({
74
74
  top: 60px;
75
75
  bottom: 0;
76
76
  left: 0;
77
- z-index: 99;
77
+ z-index: 6;
78
78
  overflow-y: scroll;
79
79
  box-shadow: 0 8px 12px var(--site-config-color-shadow);
80
80
  background: var(--site-config-color-bar);
@@ -0,0 +1,110 @@
1
+ <script lang="ts">
2
+ import config from '@config'
3
+ import { get } from 'lodash-es'
4
+ import { computed, defineComponent, onBeforeMount, onMounted, onBeforeUnmount, ref, watch, nextTick } from 'vue'
5
+ import { animationBoxData, animationEl, animationElClientRect } from '../floating'
6
+ import type { Ref, StyleValue } from 'vue'
7
+ import { useRouter } from 'vue-router'
8
+
9
+ export default defineComponent({
10
+ name: 'LogoAnimation',
11
+ setup() {
12
+ const logo: Ref<string> = get(config, 'logo')
13
+ const proxyRect: Ref<DOMRect | undefined> = ref<DOMRect>()
14
+ const floatingState: Ref<boolean> = ref<boolean>(false)
15
+
16
+ watch(animationElClientRect, async (newClientRect) => {
17
+ if (newClientRect) {
18
+ proxyRect.value = newClientRect
19
+ }
20
+ })
21
+
22
+ const styles: Ref<StyleValue | undefined> = computed(() => ({
23
+ width: `${proxyRect.value?.width}px`,
24
+ height: `${proxyRect.value?.height}px`,
25
+ top: `${proxyRect.value?.top}px`,
26
+ left: `${proxyRect.value?.left}px`,
27
+ }))
28
+
29
+ const router = useRouter()
30
+ router.beforeEach(async () => {
31
+ if (!floatingState.value) {
32
+ floatingState.value = true
33
+ }
34
+ await nextTick();
35
+ })
36
+
37
+ onBeforeMount(() => {
38
+ floatingState.value = false
39
+ })
40
+
41
+ onMounted(() => {
42
+ window.addEventListener('resize', resetPosition, false);
43
+ })
44
+
45
+ onBeforeUnmount(() => {
46
+ resetTimer && clearTimeout(resetTimer)
47
+ window.removeEventListener('resize', resetPosition);
48
+ })
49
+
50
+ const land = () => {
51
+ floatingState.value = false;
52
+ }
53
+
54
+ let resetTimer: number;
55
+
56
+ const resetPosition = async () => {
57
+ if (floatingState.value) {
58
+ floatingState.value = false
59
+ await nextTick();
60
+ }
61
+ clearTimeout(resetTimer);
62
+ const newBRect = animationEl.value?.getBoundingClientRect()
63
+ if (newBRect) {
64
+ resetTimer = window.setTimeout(() => {
65
+ proxyRect.value = newBRect
66
+ }, 200)
67
+ }
68
+ }
69
+
70
+ return {
71
+ logo,
72
+ animationBoxData,
73
+ styles,
74
+ animationEl,
75
+ floatingState,
76
+ land
77
+ }
78
+ },
79
+ })
80
+ </script>
81
+
82
+ <template>
83
+ <Teleport :to="animationEl" v-if="animationEl">
84
+ <img v-show="!floatingState" v-bind="animationBoxData.attrs" :style="styles" :src="logo" alt="logo"
85
+ v-if="logo && animationEl" class="varlet-cli-logo-animation" />
86
+ </Teleport>
87
+ <div v-show="floatingState">
88
+ <img @transitionend="land" v-bind="animationBoxData.attrs" :style="styles" :src="logo" alt="logo"
89
+ v-if="logo && animationEl"
90
+ class="varlet-cli-logo-animation varlet-cli-logo-position varlet-cli-logo-transition" />
91
+ </div>
92
+ </template>
93
+
94
+ <style lang="less">
95
+ .varlet-cli-logo-transition {
96
+ transition: 0.5s all ease-in-out;
97
+ width: 100%;
98
+ height: 100%;
99
+ display: block;
100
+ }
101
+
102
+ .varlet-cli-logo-animation {
103
+ z-index: 10;
104
+ pointer-events: none;
105
+ }
106
+
107
+ .varlet-cli-logo-position {
108
+ position: fixed;
109
+ }
110
+ </style>
@@ -0,0 +1,9 @@
1
+ import { reactive, ref } from 'vue'
2
+
3
+ // 动画节点属性存储
4
+ export const animationBoxData = reactive<any>({})
5
+
6
+ // 存储节点
7
+ export const animationEl = ref<HTMLElement | null>()
8
+
9
+ export const animationElClientRect = ref<DOMRect | null>();