valaxy-theme-hairy 0.0.9 → 0.0.13

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.
@@ -1,17 +1,30 @@
1
1
  <script lang="ts" setup>
2
2
  import { useFrontmatter } from 'valaxy'
3
- import { computed } from 'vue'
3
+ import { computed, inject, nextTick, ref } from 'vue'
4
+ import { useRouter } from 'vue-router'
4
5
  import { toArr } from '../utils'
5
6
  import { useCurrentCategory } from '../hooks/useCategory'
6
7
 
7
8
  const frontmatter = useFrontmatter()
8
9
  const paths = computed(() => toArr(frontmatter.value.categories).filter(Boolean) as string[])
9
10
  const category = useCurrentCategory(paths)
10
- const posts = computed(() => category.value.posts || [])
11
+ const posts = computed(() => {
12
+ const result = category.value.posts || []
13
+ return result.sort((a, b) => (a.date || 1) > (b.date || 1) ? 1 : -1)
14
+ })
15
+ const router = useRouter()
16
+
17
+ const active = inject('HairyUserTab:active', ref(''))
11
18
 
12
19
  function isCurrent(title = '') {
13
20
  return frontmatter.value.title === title
14
21
  }
22
+
23
+ async function changePost(path = '') {
24
+ router.push(path)
25
+ await nextTick()
26
+ active.value = 'aside'
27
+ }
15
28
  </script>
16
29
 
17
30
  <template>
@@ -20,7 +33,7 @@ function isCurrent(title = '') {
20
33
  On this Series
21
34
  </div>
22
35
  <ul class="va-toc relative z-1">
23
- <a v-for="(item, index) of posts" :key="index" class="va-toc-item" @click="$router.push(item.path || '')">
36
+ <a v-for="(item, index) of posts" :key="index" class="va-toc-item" @click="changePost(item.path)">
24
37
  <a class="outline-link" :class="[isCurrent(item.title) && 'active']">{{ index + 1 }}.{{ item.title }}</a>
25
38
  </a>
26
39
  </ul>
@@ -13,6 +13,13 @@ const text = computed(() => {
13
13
  return props.post.text
14
14
  return props.post.excerpt
15
15
  })
16
+
17
+ const Blogs = {
18
+ name: 'Mao’s blog',
19
+ desc: '记录生活、持续学习。',
20
+ link: 'https://hairy.blog/',
21
+ thumbnail: 'https://user-images.githubusercontent.com/49724027/182444624-6228d153-94cb-461d-a5d8-be8535441fb6.png',
22
+ }
16
23
  </script>
17
24
 
18
25
  <template>
@@ -2,8 +2,8 @@
2
2
  import { computed, provide, useCssVars, useSlots } from 'vue'
3
3
  import { executeOverlay } from 'unoverlay-vue'
4
4
  import type { ImageViewerProps } from 'element-plus/es/components/image-viewer/index'
5
- import type { AtWillNumber } from '@hairy/libcore'
6
- import { atWillToUnit } from '@hairy/libcore'
5
+ import type { AtWillNumber } from '../utils'
6
+ import { atWillToUnit } from '../utils'
7
7
  import HairyImageViewer from './HairyImageViewer.vue'
8
8
 
9
9
  const props = withDefaults(defineProps<{
@@ -0,0 +1,61 @@
1
+ <script lang="ts" setup>
2
+ import { defineProps } from 'vue'
3
+ defineProps<{
4
+ links?: {
5
+ name: string
6
+ url: string
7
+ image: string
8
+ color: string
9
+ desc?: string
10
+ }[]
11
+ }>()
12
+ </script>
13
+
14
+ <template>
15
+ <div class="min-h-30vh">
16
+ <div class="links">
17
+ <div v-for="(item, index) in links" :key="index" class="link-block flex items-center py-0.5rem px-1rem rounded-lg" :style="{ '--block-color': item.color }">
18
+ <a :href="item.url" class="w-4rem h-4rem">
19
+ <HairyImage class="w-full h-full rounded-xl" :src="item.image" />
20
+ </a>
21
+ <div class="pl-1rem flex-1">
22
+ <a :href="item.url" class="font-bold text-lg title">
23
+ {{ item.name }}
24
+ </a>
25
+ <div class="max-w-180px text-sm my-0.5rem truncate">
26
+ {{ item.desc }}
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </template>
33
+
34
+ <style lang="scss" scoped>
35
+ .link-block {
36
+ border: 0.0625rem solid #f7f7f7;
37
+ box-shadow: 0 0.625rem 1.875rem -0.9375rem rgba(0,0,0,0.1);
38
+ --bg-color: var(--block-color, #666);
39
+ @apply transition-all;
40
+ .title {
41
+ color: var(--block-color);
42
+ }
43
+ }
44
+ .dark .link-block {
45
+ background: rgba($color: #989898, $alpha: 0.1);
46
+ }
47
+ .links .link-block:hover {
48
+ background-color: var(--bg-color);
49
+ box-shadow: 0 0.125rem 1.25rem var(--bg-color);
50
+ border-color: var(--bg-color);
51
+ .title {
52
+ color: #fff;
53
+ }
54
+ }
55
+
56
+ .links {
57
+ display: grid;
58
+ grid-template-columns: repeat(auto-fill, 300px);
59
+ gap: 24px;
60
+ }
61
+ </style>
@@ -1,24 +1,51 @@
1
1
  <script lang="ts" setup>
2
- import type { Ref } from 'vue'
3
- import { computed } from 'vue'
2
+ import { computed, defineProps, ref, withDefaults } from 'vue'
4
3
  import type { Post } from 'valaxy'
5
4
  import { usePostList } from 'valaxy'
5
+ import { usePostLayout } from '../hooks/usePostLayout'
6
6
 
7
7
  const props = withDefaults(defineProps<{
8
8
  type?: string
9
9
  posts?: Post[]
10
+ curPage?: number
11
+ pagination?: boolean
10
12
  }>(), {
13
+ curPage: 1,
14
+ pagination: false,
11
15
  })
16
+ const layout = usePostLayout()
12
17
 
13
- const routes = usePostList() as any as Ref<Post[]>
14
- const posts = computed(() => props.posts || routes.value)
18
+ const pageSize = ref(7)
19
+ const routes = usePostList({ type: props.type || '' })
20
+ const posts = computed<any[]>(() => props.posts || routes.value)
21
+ const pagePosts = computed(() => posts.value.slice((props.curPage - 1) * pageSize.value, props.curPage * pageSize.value))
22
+ const displayedPosts = computed(() => props.pagination ? pagePosts.value : posts.value)
15
23
  </script>
16
24
 
17
25
  <template>
18
- <ul class="divide-y divide-gray-200 dark:divide-gray-700">
19
- <Transition v-for="post, i in posts" :key="i" name="fade">
20
- <HairyArticleText :post="post" />
21
- </Transition>
22
- </ul>
26
+ <HairyPostImageList v-if="layout.includes('image')" :posts="displayedPosts" />
27
+ <HairyPostTextsList v-else :posts="displayedPosts" />
28
+ <ValaxyPagination v-if="pagination" :cur-page="curPage" :page-size="pageSize" :total="posts.length" />
23
29
  </template>
24
30
 
31
+ <style lang="scss">
32
+ .pagination {
33
+ font-size: 16px;
34
+ }
35
+
36
+ .pagination .prev.active,
37
+ .pagination .next.active,
38
+ .pagination .page-number.active {
39
+ font-weight: normal;
40
+ background: transparent;
41
+ color: var(--hy-c-primary);
42
+ cursor: default;
43
+ }
44
+
45
+ .pagination .prev:hover,
46
+ .pagination .next:hover,
47
+ .pagination .page-number:hover {
48
+ color: var(--va-c-bg);
49
+ background: rgba(143, 230, 213, 0.8);
50
+ }
51
+ </style>
@@ -0,0 +1,23 @@
1
+ <script lang="ts" setup>
2
+ import type { Ref } from 'vue'
3
+ import { computed } from 'vue'
4
+ import type { Post } from 'valaxy'
5
+ import { usePostList } from 'valaxy'
6
+
7
+ const props = withDefaults(defineProps<{
8
+ type?: string
9
+ posts?: Post[]
10
+ }>(), {})
11
+
12
+ const routes = usePostList() as any as Ref<Post[]>
13
+ const posts = computed(() => props.posts || routes.value)
14
+ </script>
15
+
16
+ <template>
17
+ <ul class="divide-y divide-gray-200 dark:divide-gray-700">
18
+ <Transition v-for="post, i in posts" :key="i" name="fade">
19
+ <HairyArticleText :post="post" />
20
+ </Transition>
21
+ </ul>
22
+ </template>
23
+
@@ -1,8 +1,23 @@
1
1
  <script lang="ts" setup>
2
- import { useCategory, usePostList, useTag } from 'valaxy'
3
- const category = useCategory()
2
+ import { usePostList, useTag } from 'valaxy'
3
+ import { computed } from 'vue'
4
+ import { toArr } from '../utils'
4
5
  const posts = usePostList()
5
6
  const tags = useTag()
7
+
8
+ const total = computed(() => {
9
+ const categories = posts.value.map(v => toArr(v.categories || [])).filter(v => v.length)
10
+ const maps: string[] = []
11
+ for (const category of categories) {
12
+ let caches: string[] = []
13
+ for (const iterator of category) {
14
+ caches.push(iterator)
15
+ maps.push(caches.join('-'))
16
+ }
17
+ caches = []
18
+ }
19
+ return new Set(maps).size
20
+ })
6
21
  </script>
7
22
 
8
23
  <template>
@@ -11,7 +26,7 @@ const tags = useTag()
11
26
  文章
12
27
  </HairyUserStats>
13
28
  <div class="w-1px bg-gray bg-opacity-50" />
14
- <HairyUserStats :count="category.total" @click="$router.push('/categories/')">
29
+ <HairyUserStats :count="total" @click="$router.push('/categories/')">
15
30
  分类
16
31
  </HairyUserStats>
17
32
  <div class="w-1px bg-gray bg-opacity-50" />
@@ -2,9 +2,9 @@
2
2
  import { ElTabPane, ElTabs } from 'element-plus/es/components/tabs/index'
3
3
  import 'element-plus/es/components/tabs/style/index'
4
4
  import 'element-plus/es/components/tab-pane/style/index'
5
- import { ref } from 'vue'
6
-
5
+ import { provide, ref } from 'vue'
7
6
  const active = ref('aside')
7
+ provide('HairyUserTab:active', active)
8
8
  </script>
9
9
 
10
10
  <template>
@@ -27,17 +27,21 @@ export function useYearArchives() {
27
27
  const [year, month] = [days.format('YYYY'), days.format('MM')]
28
28
  if (!maps[year])
29
29
  maps[year] = {}
30
- if (!maps[year][month]) { maps[year][month] = { count: 1, posts: [post] } }
30
+ if (!maps[year][month]) { maps[year][month] = { count: 1, posts: [post as any] } }
31
31
  else {
32
32
  maps[year][month].count++
33
- maps[year][month].posts.push(post)
33
+ maps[year][month].posts.unshift(post as any)
34
34
  }
35
35
  }
36
36
  for (const [year, months] of Object.entries(maps)) {
37
37
  for (const [month, { count, posts }] of Object.entries(months))
38
- items.push({ year, month, count, posts })
38
+ items.unshift({ year, month, count, posts })
39
39
  }
40
- return items
40
+ return items.sort((a, b) => {
41
+ const aTime = `${a.year}-${a.month}`
42
+ const bTime = `${b.year}-${b.month}`
43
+ return bTime > aTime ? 1 : -1
44
+ })
41
45
  })
42
46
  return archives
43
47
  }
@@ -1,10 +1,13 @@
1
1
  import './loading.scss'
2
2
  import { ref } from 'vue'
3
+ import { fontFacePromise } from '../utils/fonts'
3
4
  import type { UserModule } from '..'
4
5
 
5
6
  export const install: UserModule = ({ router }) => {
6
7
  showFullLoading()
7
- router.afterEach(hideFullLoading)
8
+ router.afterEach(() => {
9
+ fontFacePromise.then(hideFullLoading)
10
+ })
8
11
  }
9
12
 
10
13
  export const isLoading = ref(false)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "valaxy-theme-hairy",
3
- "version": "0.0.9",
3
+ "version": "0.0.13",
4
4
  "packageManager": "pnpm@7.5.0",
5
5
  "author": {
6
6
  "email": "wwu710632@gmail.com",
@@ -21,7 +21,6 @@
21
21
  "dependencies": {
22
22
  "@docsearch/css": "^3.1.1",
23
23
  "@docsearch/js": "^3.1.1",
24
- "@hairy/libcore": "^0.3.0",
25
24
  "@hairy/vue-use": "^1.2.0",
26
25
  "@iconify-json/ant-design": "^1.1.3",
27
26
  "@iconify-json/simple-icons": "^1.1.19",
@@ -33,7 +33,6 @@ const post = computed(() => months.value.flatMap(item => item.posts))
33
33
  {{ month }}月
34
34
  </HairyBreadcrumbItem>
35
35
  </HairyBreadcrumb>
36
-
37
36
  <el-timeline>
38
37
  <el-timeline-item
39
38
  v-for="(item, index) in post"
@@ -26,15 +26,21 @@ const posts = usePostList()
26
26
  size="large"
27
27
  >
28
28
  <div class="activity inline-flex items-center">
29
- <HairyLink @click="$router.push(getArchiveLink(activity.year))">
29
+ <HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year))">
30
30
  {{ activity.year }}
31
31
  </HairyLink>
32
- <span class="text-gray-5 text-size-5 mx-2">/</span>
33
- <HairyLink @click="$router.push(getArchiveLink(activity.year, activity.month))">
32
+ <span class="text-gray-5 mx-2">/</span>
33
+ <HairyLink class="text-size-8" @click="$router.push(getArchiveLink(activity.year, activity.month))">
34
34
  {{ activity.month }}
35
35
  </HairyLink>
36
36
  <span class="text-gray-5 text-size-5 ml-1">({{ activity.count }}篇)</span>
37
37
  </div>
38
+ <HairyTimelinePostItem v-for="(item, index) in activity.posts.slice(0, 2)" :key="index" :post="item" />
39
+ <div v-if="activity.posts.length > 2">
40
+ <HairyLink @click="$router.push(getArchiveLink(activity.year))">
41
+ ....
42
+ </HairyLink>
43
+ </div>
38
44
  </el-timeline-item>
39
45
  </el-timeline>
40
46
  </template>
@@ -22,18 +22,20 @@ const router = useRouter()
22
22
 
23
23
  const paths = computed(() => props.categories.split('/').filter(Boolean))
24
24
  const current = useCurrentCategory(paths)
25
-
26
25
  const posts = useCategoryPost(paths)
27
26
 
28
27
  const i18n = useI18n()
29
28
 
29
+ const s = '/'
30
+
30
31
  const getBreadcrumbPath = (index: number) => {
31
- if (paths.value[index] === paths.value[paths.value.length - 1])
32
+ const paths = props.categories.split('/').filter(Boolean)
33
+ if (paths[index] === paths[paths.length - 1])
32
34
  return ''
33
- return `/categories/${paths.value.slice(0, index)}`
35
+ return `/categories/${paths.slice(0, index + 1).join('/')}`
34
36
  }
35
37
  const displayCategory = (key: string) => {
36
- router.push({ path: `/categories/${[...paths.value, key].join('/')}` })
38
+ router.push({ path: `/categories/${[key, ...paths.value].reverse().join('/')}` })
37
39
  }
38
40
  </script>
39
41
 
@@ -45,10 +47,11 @@ const displayCategory = (key: string) => {
45
47
  <HairyBreadcrumbItem :to="paths.length && '/categories/' || ''">
46
48
  全部
47
49
  </HairyBreadcrumbItem>
48
- <HairyBreadcrumbItem v-for="(key, index) in paths" :key="key" :to="getBreadcrumbPath(index)">
50
+ <HairyBreadcrumbItem v-for="(key, index) in categories.split(s)" :key="key" :to="getBreadcrumbPath(index)">
49
51
  {{ i18n.t(key) }}
50
52
  </HairyBreadcrumbItem>
51
53
  </HairyBreadcrumb>
54
+
52
55
  <div class="grid__view dark:text-gray-3 flex-wrap">
53
56
  <template v-for="([key, item]) in current.children" :key="key">
54
57
  <div
package/pages/index.vue CHANGED
@@ -1,11 +1,5 @@
1
- <script lang="ts" setup>
2
- import { usePostLayout } from '../hooks/usePostLayout'
3
- const layout = usePostLayout()
4
- </script>
5
-
6
1
  <template>
7
- <HairyPostImageList v-if="layout.includes('image')" />
8
- <HairyPostList v-else />
2
+ <HairyPostList :pagination="true" />
9
3
  </template>
10
4
 
11
5
  <route lang="yaml">
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ defineProps<{ page: string }>()
3
+ </script>
4
+
5
+ <template>
6
+ <HairyPostList :pagination="true" :cur-page="parseInt(page)" />
7
+ </template>
8
+
9
+ <route lang="yaml">
10
+ meta:
11
+ layout: home
12
+ </route>
@@ -4,7 +4,7 @@ import { useRouter } from 'vue-router'
4
4
  const router = useRouter()
5
5
 
6
6
  const { tags, getTagStyle } = useTags({
7
- primary: 'red',
7
+ primary: '#1bc9a6',
8
8
  })
9
9
 
10
10
  const displayTag = (tag: string) => {
@@ -17,7 +17,7 @@ const displayTag = (tag: string) => {
17
17
  <div text="center" class="text-size-2.5em pt-10 mb-5">
18
18
  目前共计 {{ Array.from(tags).length }} 个标签
19
19
  </div>
20
- <div text="center">
20
+ <div text="center" class="max-w-7xl flex flex-wrap justify-center items-center gap-2">
21
21
  <a v-for="[key, tag] in Array.from(tags).sort()" :key="key" class="post-tag cursor-pointer" :style="getTagStyle(tag.count)" p="1" @click="displayTag(key.toString())">
22
22
  {{ key }}
23
23
  </a>
@@ -29,3 +29,13 @@ const displayTag = (tag: string) => {
29
29
  meta:
30
30
  layout: tags
31
31
  </route>
32
+
33
+ <style lang="scss" scoped>
34
+ a {
35
+ color: var(--yun-tag-color);
36
+ &:hover {
37
+ --un-text-opacity: 1;
38
+ color: var(--hy-c-primary-dark);
39
+ }
40
+ }
41
+ </style>
@@ -14,7 +14,7 @@
14
14
  src: url('./fonts/Modesty.ttf')
15
15
  }
16
16
 
17
- @font-face {
18
- font-family: "Seto";
19
- src: url('./fonts/Seto.ttf')
20
- }
17
+ // @font-face {
18
+ // font-family: "Seto";
19
+ // src: url('./fonts/Seto.ttf')
20
+ // }
package/styles/index.scss CHANGED
@@ -65,4 +65,8 @@ body {
65
65
  .breakpoint {
66
66
  width: 75vw;
67
67
  }
68
+ }
69
+
70
+ body {
71
+ // background-image: linear-gradient(to top, #f7f7f7 0, #fdfdfd 20%) no-repeat bottom;
68
72
  }
package/utils/fonts.ts ADDED
@@ -0,0 +1,15 @@
1
+ import Seto from '../styles/fonts/Seto.ttf?url'
2
+ import { createPromise } from '.'
3
+
4
+ export const fontFacePromise = createPromise<void>()
5
+
6
+ async function loadFonts(fontFamily: string, url: string) {
7
+ const font = new FontFace(fontFamily, `url(${url})`)
8
+ await font.load()
9
+ ;(document.fonts as any).add(font)
10
+ }
11
+
12
+ (async () => {
13
+ await loadFonts('Seto', Seto)
14
+ fontFacePromise.resolve()
15
+ })()
package/utils/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { isNumber, isString } from 'lodash-es'
2
+
1
3
  /**
2
4
  * 跳转到新的页面
3
5
  * @param url 跳转url
@@ -26,3 +28,28 @@ export const toArr = <T>(arr: T[] | T): T[] => {
26
28
  return arr as any
27
29
  else return [arr].filter(Boolean) as any
28
30
  }
31
+
32
+ export type AtWillNumber = string | number
33
+
34
+ export const atWillToUnit = (value: AtWillNumber, unit = 'px') => {
35
+ if (!(isString(value) || isNumber(value)))
36
+ return ''
37
+ return isString(value) && /\D/g.test(value) ? value : value + unit
38
+ }
39
+
40
+ export interface PromiseResolver<T = void> extends Promise<T> {
41
+ resolve: (value: T) => void
42
+ reject: Function
43
+ }
44
+ export function createPromise<T>(): PromiseResolver<T> {
45
+ let resolve
46
+ let reject
47
+ // eslint-disable-next-line promise/param-names
48
+ const promise: any = new Promise((_r, _j) => {
49
+ resolve = _r
50
+ reject = _j
51
+ })
52
+ promise.resolve = resolve
53
+ promise.reject = reject
54
+ return promise as PromiseResolver<T>
55
+ }
package/valaxy.config.ts CHANGED
@@ -12,6 +12,7 @@ export default defineTheme<HairyTheme>((options) => {
12
12
  return {
13
13
  vite: images.vite,
14
14
  pages: hairy.pages,
15
+ unocss: hairy.unocss,
15
16
  extendMd(ctx) {
16
17
  hairy.extendMd?.(ctx)
17
18
  images.extendMd?.(ctx)
@@ -1,531 +0,0 @@
1
- .vp-loading {
2
- position: absolute;
3
- top: 0;
4
- left: 0;
5
- z-index: 100;
6
- width: 100vw;
7
- height: 100vh;
8
- background: #eee;
9
-
10
- transition: opacity 0.5s;
11
-
12
- .wrapper {
13
- width: 50px;
14
- height: 50px;
15
- position: fixed;
16
- top: 50%;
17
- left: 50%;
18
- margin-left: -50px;
19
- margin-top: -50px;
20
-
21
- }
22
-
23
- #preloader {
24
- width: 50px;
25
- height: 50px;
26
- border: 2px solid var(--hy-c-primary);
27
- border-radius: 0px;
28
- -webkit-animation: preloader 4.5s infinite linear;
29
- -moz-animation: preloader 4.5s infinite linear;
30
- -ms-animation: preloader 4.5s infinite linear;
31
- animation: preloader 4.5s infinite linear;
32
- }
33
-
34
- #preloader:after {
35
- content: '';
36
- width: 14px;
37
- height: 14px;
38
- background: var(--hy-c-primary);
39
- position: absolute;
40
- top: 50%;
41
- left: 50%;
42
- margin-left: -7px;
43
- margin-top: -7px;
44
- border-radius: 20px;
45
- -webkit-animation: preloader_after 4.5s infinite linear;
46
- -moz-animation: preloader_after 4.5s infinite linear;
47
- -ms-animation: preloader_after 4.5s infinite linear;
48
- animation: preloader_after 4.5s infinite linear;
49
- -webkit-transform: scale(0);
50
- }
51
-
52
- @-webkit-keyframes preloader {
53
- 0% {
54
- -webkit-transform: scale(0)
55
- }
56
-
57
- 10% {
58
- -webkit-transform: scale(1.3)
59
- }
60
-
61
- 12% {
62
- -webkit-transform: scale(1)
63
- }
64
-
65
- 15% {
66
- -webkit-transform: scale(1.3)
67
- }
68
-
69
- 17% {
70
- -webkit-transform: scale(1)
71
- }
72
-
73
- 25% {
74
- -webkit-transform: scale(1)
75
- }
76
-
77
- 40% {
78
- -webkit-transform: scale(1) rotate(180deg);
79
- border-radius: 20px;
80
- }
81
-
82
- 42% {
83
- -webkit-transform: scale(1) rotate(180deg);
84
- border-radius: 0px;
85
- }
86
-
87
- 44% {
88
- -webkit-transform: scale(1) rotate(180deg);
89
- border-radius: 20px;
90
- }
91
-
92
- 46% {
93
- -webkit-transform: scale(1) rotate(180deg);
94
- border-radius: 0px;
95
- }
96
-
97
- 48% {
98
- -webkit-transform: scale(1) rotate(180deg);
99
- border-radius: 20px;
100
- }
101
-
102
- 50% {
103
- -webkit-transform: scale(1) rotate(180deg);
104
- border-radius: 20px;
105
- }
106
-
107
- 95% {
108
- -webkit-transform: scale(1) rotate(180deg);
109
- border-radius: 20px;
110
- }
111
-
112
- 100% {
113
- -webkit-transform: scale(0) rotate(180deg);
114
- border-radius: 100px;
115
- }
116
- }
117
-
118
- @-moz-keyframes preloader {
119
- 0% {
120
- -moz-transform: scale(0)
121
- }
122
-
123
- 10% {
124
- -moz-transform: scale(1.3)
125
- }
126
-
127
- 12% {
128
- -moz-transform: scale(1)
129
- }
130
-
131
- 15% {
132
- -moz-transform: scale(1.3)
133
- }
134
-
135
- 17% {
136
- -moz-transform: scale(1)
137
- }
138
-
139
- 25% {
140
- -moz-transform: scale(1)
141
- }
142
-
143
- 40% {
144
- -moz-transform: scale(1) rotate(180deg);
145
- border-radius: 20px;
146
- }
147
-
148
- 42% {
149
- -moz-transform: scale(1) rotate(180deg);
150
- border-radius: 0px;
151
- }
152
-
153
- 44% {
154
- -moz-transform: scale(1) rotate(180deg);
155
- border-radius: 20px;
156
- }
157
-
158
- 46% {
159
- -moz-transform: scale(1) rotate(180deg);
160
- border-radius: 0px;
161
- }
162
-
163
- 48% {
164
- -moz-transform: scale(1) rotate(180deg);
165
- border-radius: 20px;
166
- }
167
-
168
- 50% {
169
- -moz-transform: scale(1) rotate(180deg);
170
- border-radius: 20px;
171
- }
172
-
173
- 95% {
174
- -moz-transform: scale(1) rotate(180deg);
175
- border-radius: 20px;
176
- }
177
-
178
- 100% {
179
- -moz-transform: scale(0) rotate(180deg);
180
- border-radius: 100px;
181
- }
182
- }
183
-
184
- @-ms-keyframes preloader {
185
- 0% {
186
- -ms-transform: scale(0)
187
- }
188
-
189
- 10% {
190
- -ms-transform: scale(1.3)
191
- }
192
-
193
- 12% {
194
- -ms-transform: scale(1)
195
- }
196
-
197
- 15% {
198
- -ms-transform: scale(1.3)
199
- }
200
-
201
- 17% {
202
- -ms-transform: scale(1)
203
- }
204
-
205
- 25% {
206
- -ms-transform: scale(1)
207
- }
208
-
209
- 40% {
210
- -ms-transform: scale(1) rotate(180deg);
211
- border-radius: 20px;
212
- }
213
-
214
- 42% {
215
- -ms-transform: scale(1) rotate(180deg);
216
- border-radius: 0px;
217
- }
218
-
219
- 44% {
220
- -ms-transform: scale(1) rotate(180deg);
221
- border-radius: 20px;
222
- }
223
-
224
- 46% {
225
- -ms-transform: scale(1) rotate(180deg);
226
- border-radius: 0px;
227
- }
228
-
229
- 48% {
230
- -ms-transform: scale(1) rotate(180deg);
231
- border-radius: 20px;
232
- }
233
-
234
- 50% {
235
- -ms-transform: scale(1) rotate(180deg);
236
- border-radius: 20px;
237
- }
238
-
239
- 95% {
240
- -ms-transform: scale(1) rotate(180deg);
241
- border-radius: 20px;
242
- }
243
-
244
- 100% {
245
- -ms-transform: scale(0) rotate(180deg);
246
- border-radius: 100px;
247
- }
248
- }
249
-
250
- @keyframes preloader {
251
- 0% {
252
- transform: scale(0)
253
- }
254
-
255
- 10% {
256
- transform: scale(1.3)
257
- }
258
-
259
- 12% {
260
- transform: scale(1)
261
- }
262
-
263
- 15% {
264
- transform: scale(1.3)
265
- }
266
-
267
- 17% {
268
- transform: scale(1)
269
- }
270
-
271
- 25% {
272
- transform: scale(1)
273
- }
274
-
275
- 40% {
276
- transform: scale(1) rotate(180deg);
277
- border-radius: 20px;
278
- }
279
-
280
- 42% {
281
- transform: scale(1) rotate(180deg);
282
- border-radius: 0px;
283
- }
284
-
285
- 44% {
286
- transform: scale(1) rotate(180deg);
287
- border-radius: 20px;
288
- }
289
-
290
- 46% {
291
- transform: scale(1) rotate(180deg);
292
- border-radius: 0px;
293
- }
294
-
295
- 48% {
296
- transform: scale(1) rotate(180deg);
297
- border-radius: 20px;
298
- }
299
-
300
- 50% {
301
- transform: scale(1) rotate(180deg);
302
- border-radius: 20px;
303
- }
304
-
305
- 95% {
306
- transform: scale(1) rotate(180deg);
307
- border-radius: 20px;
308
- }
309
-
310
- 100% {
311
- transform: scale(0) rotate(180deg);
312
- border-radius: 100px;
313
- }
314
- }
315
-
316
- @-webkit-keyframes preloader_after {
317
- 0% {
318
- -webkit-transform: scale(0);
319
- }
320
-
321
- 45% {
322
- -webkit-transform: scale(0);
323
- }
324
-
325
- 50% {
326
- -webkit-transform: scale(1);
327
- }
328
-
329
- 55% {
330
- -webkit-transform: scale(1) translateY(-20px) translateX(-14px);
331
- }
332
-
333
- 60% {
334
- -webkit-transform: scale(1) translateY(20px) translateX(14px);
335
- }
336
-
337
- 65% {
338
- -webkit-transform: scale(1) translateY(-20px) translateX(14px);
339
- }
340
-
341
- 70% {
342
- -webkit-transform: scale(1) translateY(20px) translateX(-14px);
343
- }
344
-
345
- 75% {
346
- -webkit-transform: scale(1) translateY(-20px) translateX(14px);
347
- }
348
-
349
- 80% {
350
- -webkit-transform: scale(1) translateY(20px) translateX(-14px);
351
- }
352
-
353
- 85% {
354
- -webkit-transform: scale(1) translateY(-20px) translateX(-14px);
355
- }
356
-
357
- 90% {
358
- -webkit-transform: scale(1) translateY(0px) translateX(0px);
359
- }
360
-
361
- 95% {
362
- -webkit-transform: scale(1.5);
363
- }
364
-
365
- 100% {
366
- -webkit-transform: scale(0);
367
- }
368
- }
369
-
370
- @-moz-keyframes preloader_after {
371
- 0% {
372
- -moz-transform: scale(0);
373
- }
374
-
375
- 45% {
376
- -moz-transform: scale(0);
377
- }
378
-
379
- 50% {
380
- -moz-transform: scale(1);
381
- }
382
-
383
- 55% {
384
- -moz-transform: scale(1) translateY(-20px) translateX(-14px);
385
- }
386
-
387
- 60% {
388
- -moz-transform: scale(1) translateY(20px) translateX(14px);
389
- }
390
-
391
- 65% {
392
- -moz-transform: scale(1) translateY(-20px) translateX(14px);
393
- }
394
-
395
- 70% {
396
- -moz-transform: scale(1) translateY(20px) translateX(-14px);
397
- }
398
-
399
- 75% {
400
- -moz-transform: scale(1) translateY(-20px) translateX(14px);
401
- }
402
-
403
- 80% {
404
- -moz-transform: scale(1) translateY(20px) translateX(-14px);
405
- }
406
-
407
- 85% {
408
- -moz-transform: scale(1) translateY(-20px) translateX(-14px);
409
- }
410
-
411
- 90% {
412
- -moz-transform: scale(1) translateY(0px) translateX(0px);
413
- }
414
-
415
- 95% {
416
- -moz-transform: scale(1.5);
417
- }
418
-
419
- 100% {
420
- -moz-transform: scale(0);
421
- }
422
- }
423
-
424
- @-ms-keyframes preloader_after {
425
- 0% {
426
- -ms-transform: scale(0);
427
- }
428
-
429
- 45% {
430
- -ms-transform: scale(0);
431
- }
432
-
433
- 50% {
434
- -ms-transform: scale(1);
435
- }
436
-
437
- 55% {
438
- -ms-transform: scale(1) translateY(-20px) translateX(-14px);
439
- }
440
-
441
- 60% {
442
- -ms-transform: scale(1) translateY(20px) translateX(14px);
443
- }
444
-
445
- 65% {
446
- -ms-transform: scale(1) translateY(-20px) translateX(14px);
447
- }
448
-
449
- 70% {
450
- -ms-transform: scale(1) translateY(20px) translateX(-14px);
451
- }
452
-
453
- 75% {
454
- -ms-transform: scale(1) translateY(-20px) translateX(14px);
455
- }
456
-
457
- 80% {
458
- -ms-transform: scale(1) translateY(20px) translateX(-14px);
459
- }
460
-
461
- 85% {
462
- -ms-transform: scale(1) translateY(-20px) translateX(-14px);
463
- }
464
-
465
- 90% {
466
- -ms-transform: scale(1) translateY(0px) translateX(0px);
467
- }
468
-
469
- 95% {
470
- -ms-transform: scale(1.5);
471
- }
472
-
473
- 100% {
474
- -ms-transform: scale(0);
475
- }
476
- }
477
-
478
- @keyframes preloader_after {
479
- 0% {
480
- transform: scale(0);
481
- }
482
-
483
- 45% {
484
- transform: scale(0);
485
- }
486
-
487
- 50% {
488
- transform: scale(1);
489
- }
490
-
491
- 55% {
492
- transform: scale(1) translateY(-20px) translateX(-14px);
493
- }
494
-
495
- 60% {
496
- transform: scale(1) translateY(20px) translateX(14px);
497
- }
498
-
499
- 65% {
500
- transform: scale(1) translateY(-20px) translateX(14px);
501
- }
502
-
503
- 70% {
504
- transform: scale(1) translateY(20px) translateX(-14px);
505
- }
506
-
507
- 75% {
508
- transform: scale(1) translateY(-20px) translateX(14px);
509
- }
510
-
511
- 80% {
512
- transform: scale(1) translateY(20px) translateX(-14px);
513
- }
514
-
515
- 85% {
516
- transform: scale(1) translateY(-20px) translateX(-14px);
517
- }
518
-
519
- 90% {
520
- transform: scale(1) translateY(0px) translateX(0px);
521
- }
522
-
523
- 95% {
524
- transform: scale(1.5);
525
- }
526
-
527
- 100% {
528
- transform: scale(0);
529
- }
530
- }
531
- }
package/utils/loading.ts DELETED
@@ -1,30 +0,0 @@
1
- import './loading.scss'
2
-
3
- function createElement() {
4
- const loadingEl = document.createElement('div')
5
- loadingEl.className = 'vp-loading'
6
- loadingEl.innerHTML = `\
7
- <div class="wrapper">
8
- <div id="preloader"></div>
9
- </div>
10
- `
11
- return loadingEl
12
- }
13
-
14
- let el: HTMLElement
15
-
16
- export function showFullLoading() {
17
- if (!el)
18
- el = createElement()
19
- el.style.opacity = '0'
20
- document.body.appendChild(el)
21
- setTimeout(() => el.style.opacity = '1')
22
- }
23
-
24
- export function hideFullLoading() {
25
- if (!el)
26
- return
27
- el.style.opacity = '0'
28
- setTimeout(() => el.remove(), 500)
29
- }
30
-