Add mobile compatibility

This commit is contained in:
mashirozx 2021-08-04 23:57:10 +08:00
parent e7480f90ab
commit 14f56dab39
28 changed files with 1694 additions and 442 deletions

View File

@ -5,7 +5,8 @@
"view": "div[class=${1}]", "view": "div[class=${1}]",
"text": "span[class=\"text\"]", "text": "span[class=\"text\"]",
"image": "Image[src=${1} placeholder=${2} :avatar=\"false\" alt=${2} :draggable=\"false\"]", "image": "Image[src=${1} placeholder=${2} :avatar=\"false\" alt=${2} :draggable=\"false\"]",
"icon": "UiIcon[name=${1} :width=\"100%\" :height=\"100%\"]" "icon": "UiIcon[name=${1} :width=\"100%\" :height=\"100%\"]",
"slot": "slot[name=${1}]"
} }
} }
} }

View File

@ -29,21 +29,21 @@
}, },
"dependencies": { "dependencies": {
"@formatjs/intl": "^1.13.4", "@formatjs/intl": "^1.13.4",
"@material/button": "^13.0.0-canary.5981207f7.0", "@material/button": "^13.0.0-canary.b47dd37a6.0",
"@material/card": "^13.0.0-canary.5981207f7.0", "@material/card": "^13.0.0-canary.b47dd37a6.0",
"@material/checkbox": "^13.0.0-canary.5981207f7.0", "@material/checkbox": "^13.0.0-canary.b47dd37a6.0",
"@material/chips": "^13.0.0-canary.5981207f7.0", "@material/chips": "^13.0.0-canary.b47dd37a6.0",
"@material/dialog": "^13.0.0-canary.5981207f7.0", "@material/dialog": "^13.0.0-canary.b47dd37a6.0",
"@material/elevation": "^13.0.0-canary.5981207f7.0", "@material/elevation": "^13.0.0-canary.b47dd37a6.0",
"@material/form-field": "^13.0.0-canary.5981207f7.0", "@material/form-field": "^13.0.0-canary.b47dd37a6.0",
"@material/menu": "^13.0.0-canary.5981207f7.0", "@material/menu": "^13.0.0-canary.b47dd37a6.0",
"@material/radio": "^13.0.0-canary.5981207f7.0", "@material/radio": "^13.0.0-canary.b47dd37a6.0",
"@material/ripple": "^13.0.0-canary.5981207f7.0", "@material/ripple": "^13.0.0-canary.b47dd37a6.0",
"@material/switch": "^13.0.0-canary.5981207f7.0", "@material/switch": "^13.0.0-canary.b47dd37a6.0",
"@material/tab-bar": "^13.0.0-canary.5981207f7.0", "@material/tab-bar": "^13.0.0-canary.b47dd37a6.0",
"@material/textfield": "^13.0.0-canary.5981207f7.0", "@material/textfield": "^13.0.0-canary.b47dd37a6.0",
"@material/theme": "^13.0.0-canary.5981207f7.0", "@material/theme": "^13.0.0-canary.b47dd37a6.0",
"@material/typography": "^13.0.0-canary.5981207f7.0", "@material/typography": "^13.0.0-canary.b47dd37a6.0",
"@vueuse/core": "^5.2.0", "@vueuse/core": "^5.2.0",
"@yzfe/svgicon": "^1.0.1", "@yzfe/svgicon": "^1.0.1",
"@yzfe/vue3-svgicon": "^1.0.1", "@yzfe/vue3-svgicon": "^1.0.1",
@ -51,6 +51,7 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"camelcase-keys": "^7.0.0", "camelcase-keys": "^7.0.0",
"chroma-js": "^2.1.2", "chroma-js": "^2.1.2",
"cooltipz-css": "^1.6.8",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"gsap": "^3.7.0", "gsap": "^3.7.0",
"highlight.js": "^11.1.0", "highlight.js": "^11.1.0",
@ -61,10 +62,12 @@
"perfect-scrollbar": "^1.5.2", "perfect-scrollbar": "^1.5.2",
"snakecase-keys": "^4.0.2", "snakecase-keys": "^4.0.2",
"swiper": "^6.7.5", "swiper": "^6.7.5",
"tippy.js": "^6.3.1",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"vue": "^3.1.4", "vue": "^3.1.4",
"vue-intl": "^6.0.6", "vue-intl": "^6.0.6",
"vue-router": "^4.0.10" "vue-router": "^4.0.10",
"vue-tippy": "^6.0.0-alpha.31"
}, },
"devDependencies": { "devDependencies": {
"@amatlash/vite-plugin-stylelint": "^1.1.1", "@amatlash/vite-plugin-stylelint": "^1.1.1",

View File

@ -134,6 +134,7 @@ interface CommentStore {
declare type FetchingStatus = declare type FetchingStatus =
| 'inite' | 'inite'
| 'cached' | 'cached'
| 'updating'
| 'pending' | 'pending'
| 'success' | 'success'
| 'error' | 'error'

View File

@ -1,7 +1,21 @@
<template> <template>
<div class="comment__container"> <div class="comment__container">
<h1>Comments</h1> <h3 class="comment-list__title" :ref="setCommentListTitleRef">
<div class="comment-list__wripper"> <span>{{ msg.comments.heading }}</span>
<span>{{ msg.comments.commentCount.value }}</span>
<!-- // TODO: Is it a but that nested reactive value cannot be destructured in template? -->
</h3>
<div class="updating-status__wrapper">
<Toggler :show="shouldShowUpdatingStatus">
<div class="content__wrapper">
<div class="content" :data-status="fetchStatus">
<i :class="updatingLatestIcon"></i>&nbsp;
{{ updatingLatestMsg }}
</div>
</div>
</Toggler>
</div>
<div class="comment-list__wrapper" v-if="commentData.length > 0 || true">
<CommentList <CommentList
:data="commentData" :data="commentData"
:page="page" :page="page"
@ -9,12 +23,17 @@
:totalPage="totalPage" :totalPage="totalPage"
></CommentList> ></CommentList>
</div> </div>
<div class="pagination__wrapper"> <div class="loader__wrapper" v-show="fetchStatus === 'pending'">
<BookLoader></BookLoader>
</div>
<div class="error__wrapper" v-show="fetchStatus === 'error'">
<ErrorRefresher @refresh="handleRefreshEvent"></ErrorRefresher>
</div>
<div class="pagination__wrapper" v-if="totalPage > 1">
<Pagination <Pagination
:current="page" :current="$props.order === 'desc' ? totalPage - page + 1 : page"
:total="totalPage" :total="totalPage"
@change:current="handlePageChangeEvent" @change:current="handlePageChangeEvent"
v-if="totalPage > 1"
></Pagination> ></Pagination>
</div> </div>
<div class="composer__wrapper"> <div class="composer__wrapper">
@ -24,21 +43,36 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, watch, computed, toRefs, onMounted, nextTick, ref, Comment } from 'vue' import { defineComponent, watch, computed, toRefs, onMounted, nextTick, ref } from 'vue'
import type { Ref } from 'vue'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import camelcaseKeys from 'camelcase-keys' import camelcaseKeys from 'camelcase-keys'
import { useInjector, useState, useRoute, useMessage, useIntl } from '@/hooks' import {
useInjector,
useState,
useRoute,
useMessage,
useIntl,
useScrollToElement,
useElementRef,
} from '@/hooks'
import { comments } from '@/store' import { comments } from '@/store'
import API from '@/api' import API from '@/api'
import axiosErrorHandler from '@/utils/axiosErrorHandler' import axiosErrorHandler from '@/utils/axiosErrorHandler'
import CommentList from './CommentList.vue' import CommentList from './CommentList.vue'
import Pagination from '@/components/pagination/Pagination.vue' import Pagination from '@/components/pagination/Pagination.vue'
import Composer from './Composer.vue' import Composer from './Composer.vue'
import ErrorRefresher from '../status/ErrorRefresher.vue'
import BookLoader from '@/components/loader/BookLoader.vue'
import Toggler from '@/components/toggler/Toggler.vue'
export default defineComponent({ export default defineComponent({
components: { CommentList, Pagination, Composer }, components: { CommentList, Pagination, Composer, BookLoader, Toggler, ErrorRefresher },
props: { props: {
postId: Number, postId: Number,
order: { type: String, default: 'desc' }, // order: 'desc', orderby: 'date_gmt'
orderby: { type: String, default: 'date_gmt' },
commentTotalCount: { type: Number, default: 0 },
}, },
setup(props) { setup(props) {
const addMessage = useMessage() const addMessage = useMessage()
@ -54,32 +88,62 @@ export default defineComponent({
const [page, setPage] = useState(1) const [page, setPage] = useState(1)
const [perPage, setPerpage] = useState(10) const [perPage, setPerpage] = useState(10)
const [totalPage, setTotalPage] = useState(1) const [totalPage, setTotalPage] = useState(1)
const [totalCount, setTotalCount] = useState(props.commentTotalCount)
const [commentData, setCommentData] = useState([] as Comment[]) const [commentData, setCommentData] = useState([] as Comment[])
const [fetchStatus, setFetchStatus] = useState('inite' as FetchingStatus)
const [willGetFromCache, setWillGetFromCache] = useState(false)
const [CommentListTitleRef, setCommentListTitleRef] = useElementRef()
const scrollToCommentListWrapperTop = useScrollToElement(
CommentListTitleRef as Ref<HTMLElement>,
'top',
'top'
)
const namespace = computed(() => `comment-for-post-${postId.value}`) const namespace = computed(() => `comment-for-post-${postId.value}`)
const fetchComments = (page: number, perPage: number) => { const fetchComments = async (page: number, perPage: number) => {
if (willGetFromCache.value) {
setFetchStatus('updating')
} else {
setFetchStatus('pending')
}
setWillGetFromCache(false)
fetchComment({ fetchComment({
state: commentStore, state: commentStore,
namespace: namespace.value, namespace: namespace.value,
opts: { post: postId.value, page, perPage }, opts: { post: postId.value, page, perPage, order: props.order, orderby: props.orderby },
}).then(() => { addMessage,
})
.then(() => {
getComments(page) getComments(page)
setFetchStatus('success')
})
.catch(() => {
setFetchStatus('error')
}) })
} }
const getComments = (page: number) => { const getComments = (page: number, tryToGetFromCache = false) => {
const newData = getCommentList({ state: commentStore, namespace: namespace.value, page }) const newData = getCommentList({ state: commentStore, namespace: namespace.value, page })
if (!newData) return if (!newData?.data) {
if (tryToGetFromCache) setWillGetFromCache(false)
setCommentData([])
} else {
if (tryToGetFromCache) {
setWillGetFromCache(true)
} else {
setWillGetFromCache(false)
}
setCommentData(newData.data) setCommentData(newData.data)
setPage(page)
setPerpage(newData.pagination.perPage) setPerpage(newData.pagination.perPage)
setTotalPage(newData.pagination.totalPage) setTotalPage(newData.pagination.totalPage)
setTotalCount(newData.pagination.totalCount)
}
setPage(page)
} }
// const [composerRef,setComposerRef]=useElementRef()
const composerRef = ref<InstanceType<typeof Composer>>() const composerRef = ref<InstanceType<typeof Composer>>()
const createComment = ({ const createComment = ({
@ -98,6 +162,7 @@ export default defineComponent({
const _commentData = cloneDeep(commentData.value) as Comment[] const _commentData = cloneDeep(commentData.value) as Comment[]
_commentData.push(camelcaseKeys(res.data)) _commentData.push(camelcaseKeys(res.data))
setCommentData(_commentData) setCommentData(_commentData)
setTotalCount(totalCount.value + 1)
// console.log(res.data, commentData.value) // console.log(res.data, commentData.value)
addMessage({ addMessage({
type: 'success', type: 'success',
@ -120,8 +185,15 @@ export default defineComponent({
} }
const handlePageChangeEvent = (page: number) => { const handlePageChangeEvent = (page: number) => {
getComments(page) if (props.order === 'desc') {
fetchComments(page, perPage.value) const target = totalPage.value - page + 1
getComments(target, true)
fetchComments(target, perPage.value).then(() => setWillGetFromCache(false))
} else {
getComments(page, true)
fetchComments(page, perPage.value).then(() => setWillGetFromCache(false))
}
scrollToCommentListWrapperTop()
} }
const handleSubmitCommentEvent = (event: { const handleSubmitCommentEvent = (event: {
@ -135,6 +207,7 @@ export default defineComponent({
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
setWillGetFromCache(true)
getComments(page.value) getComments(page.value)
}) })
watch( watch(
@ -147,7 +220,82 @@ export default defineComponent({
) )
}) })
const msg = {
updatingLatest: {
updating: intl.formatMessage({
id: 'messages.commentList.cache.updating',
defaultMessage: 'Updating the latest comment list...',
}),
success: intl.formatMessage({
id: 'messages.commentList.cache.updateSuccess',
defaultMessage: 'Comment list updated.',
}),
error: intl.formatMessage({
id: 'messages.commentList.cache.updateError',
defaultMessage: 'Opps! Something went wrong when updating comment list.',
}),
},
comments: {
heading: intl.formatMessage({
id: 'messages.commentList.title.heading',
defaultMessage: 'Comments',
}),
commentCount: computed(() =>
intl.formatMessage(
{
id: 'messages.commentList.title.commentCount',
defaultMessage:
'{commentCount, plural, =0 {Be the first one to leave a comment!} =1 {One comment} other {{commentCount, number, ::compact-short} Comments}}',
},
{ commentCount: totalCount.value }
)
),
},
}
const updatingLatestMsg = computed(() => {
if (Object.hasOwnProperty.call(msg.updatingLatest, fetchStatus.value)) {
return msg.updatingLatest[fetchStatus.value as keyof typeof msg.updatingLatest]
}
})
const updatingLatestIcon = computed(() => {
switch (fetchStatus.value) {
case 'updating':
return 'fas fa-sync fa-spin'
case 'success':
return 'fas fa-check'
case 'error':
return 'fas fa-times'
default:
return ''
}
})
const [shouldShowUpdatingStatus, setShouldShowUpdatingStatus] = useState(false)
watch(fetchStatus, (value) => {
if (value === 'updating') {
setShouldShowUpdatingStatus(true)
} else {
window.setTimeout(() => setShouldShowUpdatingStatus(false), 1000)
}
})
const handleRefreshEvent = () => {
setWillGetFromCache(false)
fetchComments(page.value, perPage.value)
}
watch(
() => props.commentTotalCount,
(value) => {
setTotalCount(value)
}
)
return { return {
commentStore, // debug
msg,
fetchStatus,
postId, postId,
page, page,
setPage, setPage,
@ -157,6 +305,11 @@ export default defineComponent({
handlePageChangeEvent, handlePageChangeEvent,
handleSubmitCommentEvent, handleSubmitCommentEvent,
composerRef, composerRef,
setCommentListTitleRef,
updatingLatestMsg,
updatingLatestIcon,
shouldShowUpdatingStatus,
handleRefreshEvent,
} }
}, },
}) })
@ -169,6 +322,10 @@ export default defineComponent({
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
> * { > * {
padding: 12px 0;
width: 100%;
}
.error__wrapper {
padding-top: 12px; padding-top: 12px;
width: 100%; width: 100%;
} }
@ -179,5 +336,54 @@ export default defineComponent({
.composer__wrapper { .composer__wrapper {
width: 100%; width: 100%;
} }
.comment-list__title {
width: 100%;
margin: 0 auto;
color: #7d7d7d;
font-weight: 400;
span {
&:first-child {
padding-right: 6px;
&::after {
content: '|';
padding-left: 6px;
}
}
// &:last-child {
// padding-left: 6px;
// }
}
}
// .comment-list__wrapper {
// }
.updating-status__wrapper {
width: 100%;
padding: 0;
.content__wrapper {
width: 100%;
padding-bottom: 12px;
.content {
width: calc(100% - 24px);
padding: 12px;
border-radius: 4px;
text-align: center;
background: transparent;
color: transparent;
transition: all 0.2s;
&[data-status='updating'] {
background: #39c0ed;
color: #ffffff;
}
&[data-status='success'] {
background: #acda78;
color: #ffffff;
}
&[data-status='error'] {
background: #f93154;
color: #ffffff;
}
}
}
}
} }
</style> </style>

View File

@ -1,8 +1,10 @@
<template> <template>
<div class="comment-list__container"> <div class="comment-list__container">
<div class="item__wrapper" v-for="(item, index) in $props.data" :key="index"> <transition-group name="comment-list" tag="div">
<div class="item__wrapper" v-for="(item, index) in $props.data" :key="index + item.id">
<CommentListItem :data="item"></CommentListItem> <CommentListItem :data="item"></CommentListItem>
</div> </div>
</transition-group>
</div> </div>
</template> </template>
@ -17,6 +19,20 @@ export default defineComponent({
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.comment-list {
&-enter-active {
animation: lightSpeedInLeft /* animate.css */ 1s ease-in;
}
// &-leave-active {
// position: absolute;
// transform-origin: center center;
// animation: lightSpeedOutRight /* animate.css */ 1s ease-in;
// }
&-move {
transition: transform 0.3s ease;
transition-delay: 0.3s;
}
}
.item__wrapper { .item__wrapper {
&:not(:first-child) { &:not(:first-child) {
padding-top: 12px; padding-top: 12px;

View File

@ -1,14 +1,83 @@
<template> <template>
<div class="composer__container"> <div class="composer__container">
<div class="row__wrapper--tips">
<span><i class="fab fa-markdown"></i> {{ messages.markdownTips }}</span>
</div>
<div class="row__wrapper--textarea"> <div class="row__wrapper--textarea">
<img
class="background"
src="https://view.moezx.cc/images/2018/03/24/comment-bg.png"
:data-show="inputContent.trim().length === 0"
/>
<OutlinedTextarea <OutlinedTextarea
v-model:content="inputContent" v-model:content="inputContent"
:label="messages.textareaLabel" :label="messages.textareaLabel"
:enableResizer="true" :enableResizer="true"
:enableCounter="true"
:maxlength="99999"
></OutlinedTextarea> ></OutlinedTextarea>
<div class="toolkits__wrapper">
<div class="toolkits__container">
<span class="markdown__tip" ref="toolkitMarkdownRef">
<i class="fab fa-markdown"></i>
</span>
<span class="emoji__tool" ref="toolkitEmojiRef">
<i class="far fa-laugh-squint"></i>
</span>
<span class="image__tool" ref="toolkitImageRef">
<i class="far fa-image"></i>
</span>
<span class="preview__tool" ref="toolkitPreviewRef">
<i class="fas fa-glasses"></i>
</span>
<span
class="privacy__tool"
ref="toolkitPrivacyRef"
@click="handleTogglePrivacyOptionsEvent"
>
<i class="fas fa-user-shield"></i>
</span>
</div>
</div>
</div>
<div class="row__wrapper--privacy">
<Toggler :show="shouldShowPrivacyOptions">
<div class="options__wrapper">
<div class="option visibility">
<span>
<i class="fas fa-lock"></i>
{{ messages.privacy.visibility.title }}
</span>
<Switcher
v-model:checked="privacyIsPrivate"
positiveLabel=""
negativeLabel=""
></Switcher>
</div>
<!-- <i class="fas fa-unlock"></i> -->
<!-- <i class="fas fa-globe"></i> -->
<div class="option anynomous">
<span>
<i class="fas fa-user-secret"></i>
{{ messages.privacy.anynomous.title }}
</span>
<Switcher
v-model:checked="privacyIsAnynomous"
positiveLabel=""
negativeLabel=""
></Switcher>
</div>
<!-- <i class="fas fa-theater-masks"></i> -->
<div class="option inform">
<span>
<i class="fas fa-envelope"></i>
{{ messages.privacy.email.title }}
</span>
<Switcher
v-model:checked="privacyShouldInform"
positiveLabel=""
negativeLabel=""
></Switcher>
</div>
</div>
</Toggler>
</div> </div>
<div class="row__wrapper--profile"> <div class="row__wrapper--profile">
<div class="flex-box"> <div class="flex-box">
@ -47,7 +116,6 @@
</div> </div>
</div> </div>
</div> </div>
<!-- <div class="row__wrapper--options"></div> -->
<!-- <div class="captcha-button"> <!-- <div class="captcha-button">
<Captcha></Captcha> <Captcha></Captcha>
</div> --> </div> -->
@ -63,43 +131,89 @@
<script lang="ts"> <script lang="ts">
import { defineComponent, ref } from 'vue' import { defineComponent, ref } from 'vue'
import { useTippy } from 'vue-tippy'
import { useIntl, useState } from '@/hooks' import { useIntl, useState } from '@/hooks'
import gravatar, { WP_DEFAULT_USER_EMAIL } from '@/utils/gravatar' import gravatar, { WP_DEFAULT_USER_EMAIL } from '@/utils/gravatar'
import Captcha from './Captcha.vue' import Captcha from './Captcha.vue'
import OutlinedInput from '@/components/inputs/OutlinedInput.vue' import OutlinedInput from '@/components/inputs/OutlinedInput.vue'
import OutlinedTextarea from '@/components/inputs/OutlinedTextarea.vue' import OutlinedTextarea from '@/components/inputs/OutlinedTextarea.vue'
import NormalButton from '@/components/buttons/NormalButton.vue' import NormalButton from '@/components/buttons/NormalButton.vue'
import Toggler from '@/components/toggler/Toggler.vue'
import Switcher from '@/components/switcher/Switcher.vue'
export default defineComponent({ export default defineComponent({
components: { Captcha, OutlinedInput, OutlinedTextarea, NormalButton }, components: { Captcha, OutlinedInput, OutlinedTextarea, NormalButton, Toggler, Switcher },
emits: ['submit'], emits: ['submit'],
setup(props, { emit }) { setup(props, { emit }) {
const Intl = useIntl() const intl = useIntl()
const messages = { const messages = {
markdownTips: Intl.formatMessage({ markdownTips: intl.formatMessage({
id: 'posts.comment.composer.tips.markdownSupported', id: 'posts.comment.composer.tips.markdownSupported',
defaultMessage: 'Markdown Supported', defaultMessage: 'Markdown Supported',
}), }),
textareaLabel: Intl.formatMessage({ textareaLabel: intl.formatMessage({
id: 'posts.comment.composer.content.label', id: 'posts.comment.composer.content.label',
defaultMessage: 'You are a surprise that I will only meet once in my life', defaultMessage: 'You are a surprise that I will only meet once in my life',
}), }),
nickname: Intl.formatMessage({ nickname: intl.formatMessage({
id: 'posts.comment.composer.authorName.label', id: 'posts.comment.composer.authorName.label',
defaultMessage: 'Nickname *', defaultMessage: 'Nickname *',
}), }),
email: Intl.formatMessage({ email: intl.formatMessage({
id: 'posts.comment.composer.authorEmail.label', id: 'posts.comment.composer.authorEmail.label',
defaultMessage: 'Email *', defaultMessage: 'Email *',
}), }),
link: Intl.formatMessage({ link: intl.formatMessage({
id: 'posts.comment.composer.authorUrl.label', id: 'posts.comment.composer.authorUrl.label',
defaultMessage: 'Link', defaultMessage: 'Link',
}), }),
submit: Intl.formatMessage({ submit: intl.formatMessage({
id: 'posts.comment.composer.submit.button', id: 'posts.comment.composer.submit.button',
defaultMessage: 'Submit', defaultMessage: 'Submit',
}), }),
toolkits: {
previewTooltip: intl.formatMessage({
id: 'posts.comment.composer.toolkits.preview.tooltip',
defaultMessage: '\'<i class="fab fa-markdown"></i>\' Markdown preview',
}),
emojiTooltip: intl.formatMessage({
id: 'posts.comment.composer.toolkits.emoji.tooltip',
defaultMessage: 'Insert emoji',
}),
imageTooltip: intl.formatMessage({
id: 'posts.comment.composer.toolkits.image.tooltip',
defaultMessage: 'Attach image',
}),
privacyTooltip: intl.formatMessage({
id: 'posts.comment.composer.toolkits.privacy.tooltip',
defaultMessage: 'Privacy settings',
}),
markdownTooltip: intl.formatMessage({
id: 'posts.comment.composer.toolkits.preview.tooltip',
defaultMessage:
'\'<a href="https://guides.github.com/features/mastering-markdown/" target="_blank">Markdown</a>\' supported',
}),
},
privacy: {
anynomous: {
title: intl.formatMessage({
id: 'posts.comment.composer.privacy.anynomous.title',
defaultMessage: 'Comment as anynomous user',
}),
},
visibility: {
title: intl.formatMessage({
id: 'posts.comment.composer.privacy.visibility.title',
defaultMessage: 'Secret comment (only admins and peoples mentioned can see)',
}),
},
email: {
title: intl.formatMessage({
id: 'posts.comment.composer.privacy.email.title',
defaultMessage: 'Inform me with email when receive reply',
}),
},
},
} }
const inputContent = ref('') const inputContent = ref('')
@ -107,6 +221,10 @@ export default defineComponent({
const inputAuthorEmail = ref('') const inputAuthorEmail = ref('')
const inputAuthorUrl = ref('') const inputAuthorUrl = ref('')
const privacyIsPrivate = ref(false)
const privacyIsAnynomous = ref(false)
const privacyShouldInform = ref(true)
// TODO: debounce // TODO: debounce
const handleSubmitEvent = () => { const handleSubmitEvent = () => {
emit('submit', { emit('submit', {
@ -124,6 +242,44 @@ export default defineComponent({
const clearInputContent = () => (inputContent.value = '') const clearInputContent = () => (inputContent.value = '')
const toolkitEmojiRef = ref()
const toolkitPreviewRef = ref()
const toolkitImageRef = ref()
const toolkitPrivacyRef = ref()
const toolkitMarkdownRef = ref()
const commonTippyOpts = {
animation: 'scale',
theme: 'material',
}
const { tippy: tippyToolkitEmoji } = useTippy(toolkitEmojiRef, {
content: messages.toolkits.emojiTooltip,
...commonTippyOpts,
})
const { tippy: tippyToolkitPreview } = useTippy(toolkitPreviewRef, {
content: messages.toolkits.previewTooltip,
allowHTML: true,
...commonTippyOpts,
})
const { tippy: tippyToolkitImage } = useTippy(toolkitImageRef, {
content: messages.toolkits.imageTooltip,
...commonTippyOpts,
})
const { tippy: tippyToolkitPrivacy } = useTippy(toolkitPrivacyRef, {
content: messages.toolkits.privacyTooltip,
...commonTippyOpts,
})
const { tippy: tippyToolkitMarkdown } = useTippy(toolkitMarkdownRef, {
content: messages.toolkits.markdownTooltip,
allowHTML: true,
interactive: true,
...commonTippyOpts,
})
const [shouldShowPrivacyOptions, setShouldShowPrivacyOptions] = useState(false)
const handleTogglePrivacyOptionsEvent = () =>
setShouldShowPrivacyOptions(!shouldShowPrivacyOptions.value)
return { return {
messages, messages,
inputContent, inputContent,
@ -134,6 +290,16 @@ export default defineComponent({
handleSubmitEvent, handleSubmitEvent,
handleEmailInputBlurEvent, handleEmailInputBlurEvent,
clearInputContent, clearInputContent,
toolkitEmojiRef,
toolkitPreviewRef,
toolkitImageRef,
toolkitPrivacyRef,
toolkitMarkdownRef,
shouldShowPrivacyOptions,
handleTogglePrivacyOptionsEvent,
privacyIsPrivate,
privacyIsAnynomous,
privacyShouldInform,
} }
}, },
}) })
@ -147,22 +313,65 @@ export default defineComponent({
> * { > * {
width: 100%; width: 100%;
padding-top: 12px; padding-top: 12px;
&:first-child {
padding-top: 0;
}
} }
> .row__wrapper { > .row__wrapper {
&--tips { &--textarea {
position: relative;
width: 100%;
.background {
position: absolute;
bottom: 32px;
right: 0;
z-index: -1;
max-height: 200px;
max-width: 100%;
opacity: 0;
transition: opacity 0.5s;
&[data-show='true'] {
opacity: 1;
}
}
.toolkits__wrapper {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 36px;
display: flex;
justify-content: flex-start;
align-items: center;
.toolkits__container {
padding-left: 12px;
display: flex;
flex-flow: row nowrap;
justify-content: flex-end;
align-items: center;
@include polyfills.flex-gap(12px, 'row nowrap');
> * {
width: 20px;
height: 20px;
}
span { span {
line-height: 24px; line-height: 24px;
font-size: medium; font-size: medium;
color: #404040; color: #404040;
} }
} }
&--textarea { }
}
&--privacy {
width: 100%; width: 100%;
::v-deep(.mdc-text-field__resizer) { .options__wrapper {
background-image: url(https://view.moezx.cc/images/2018/03/24/comment-bg.png); .option {
background-size: contain; display: flex;
background-repeat: no-repeat; flex-flow: row nowrap;
background-position: right; justify-content: flex-start;
align-items: center;
@include polyfills.flex-gap(12px, 'row nowrap');
}
} }
} }
&--profile { &--profile {

View File

@ -0,0 +1,54 @@
<template>
<div class="error-refresher__wrapper">
<div class="button" @click="handleRefreshEvent">
<i class="fas fa-sync-alt"></i>
</div>
<div class="desc">
{{ msg }}
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useIntl } from '@/hooks'
export default defineComponent({
emits: ['refresh'],
setup(props, { emit }) {
const intl = useIntl()
const msg = intl.formatMessage({
id: 'messages.content.status.errorLoadingComponent',
defaultMessage: 'Something went wrong when loading this component.',
})
const handleRefreshEvent = () => emit('refresh', true)
return { msg, handleRefreshEvent }
},
})
</script>
<style lang="scss" scoped>
.error-refresher__wrapper {
width: 100%;
display: flex;
flex-flow: column nowrap;
align-items: center;
.button {
font-size: 64px;
width: 80px;
height: 80px;
line-height: 64px;
color: #5d5d5d;
cursor: pointer;
}
.desc {
padding-top: 12px;
font-size: 15px;
font-weight: 400;
color: #5d5d5d;
text-align: center;
}
}
</style>

View File

@ -110,8 +110,6 @@ export default defineComponent({
const next = () => { const next = () => {
if (currentPage.value + 1 <= totalPage.value) { if (currentPage.value + 1 <= totalPage.value) {
console.log(currentPage.value, totalPage.value)
setCurrentPageCached(currentPage.value) setCurrentPageCached(currentPage.value)
setCurrentPage(currentPage.value + 1) setCurrentPage(currentPage.value + 1)
fetch().then(() => setCurrentPageCached(currentPage.value)) fetch().then(() => setCurrentPageCached(currentPage.value))
@ -201,7 +199,7 @@ export default defineComponent({
} }
> .post-thumb-card__wrapper { > .post-thumb-card__wrapper {
width: auto; width: auto;
padding-top: 24px; padding-top: 24px; // TODO
} }
> .loader__wrapper { > .loader__wrapper {
padding-top: 24px; padding-top: 24px;

View File

@ -0,0 +1,40 @@
<template>
<div class="ripple__container">
<div class="ripple__content mdc-list-item" :ref="setContainerRef">
<div class="mdc-list-item__ripple"></div>
<div class="slot__wrapper">
<slot></slot>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useMDCRipple, useElementRef } from '@/hooks'
export default defineComponent({
setup() {
const [containerRef, setContainerRef] = useElementRef()
useMDCRipple(containerRef)
return { setContainerRef }
},
})
</script>
<style lang="scss" scoped>
.ripple__container {
width: 100%;
height: 100%;
.ripple__content {
width: 100%;
height: 100%;
padding-left: 0;
padding-right: 0;
.slot__wrapper {
width: 100%;
height: 100%;
}
}
}
</style>

View File

@ -0,0 +1,47 @@
<template>
<div class="toggler__container">
<div
class="toggler__content"
:style="{ maxHeight: $props.show ? `${expandContentHeight}px` : '0px' }"
>
<div class="content" :ref="setExpandContentRef">
<slot></slot>
</div>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
import { useElementRef, useResizeObserver } from '@/hooks'
export default defineComponent({
props: { show: Boolean },
setup() {
const [expandContentRef, setExpandContentRef] = useElementRef()
const expandContentSize = useResizeObserver(expandContentRef)
const expandContentHeight = computed(() =>
isNaN(expandContentSize.value.height)
? 0
: expandContentSize.value.height + expandContentSize.value.paddingTop
)
return { setExpandContentRef, expandContentHeight }
},
})
</script>
<style lang="scss" scoped>
.toggler__container {
width: 100%;
.toggler__content {
width: 100%;
max-height: 0;
transition: max-height 0.3s ease-in-out;
overflow: hidden;
> .content {
width: 100%;
}
}
}
</style>

View File

@ -0,0 +1,316 @@
<template>
<div class="wrapper">
<input type="checkbox" />
<div class="btn"></div>
<div class="tooltip">
<svg>
<use xlink:href="#icon-01" class="icon icon-01" />
</svg>
<svg>
<use xlink:href="#icon-02" class="icon icon-02" />
</svg>
<svg>
<use xlink:href="#icon-03" class="icon icon-03" />
</svg>
</div>
<svg>
<use xlink:href="#shape-01" class="shape shape-01" />
<use xlink:href="#shape-02" class="shape shape-02" />
<use xlink:href="#shape-03" class="shape shape-03" />
<use xlink:href="#shape-04" class="shape shape-04" />
<use xlink:href="#shape-05" class="shape shape-05" />
<use xlink:href="#shape-06" class="shape shape-06" />
<use xlink:href="#shape-07" class="shape shape-07" />
<use xlink:href="#shape-08" class="shape shape-08" />
<use xlink:href="#shape-09" class="shape shape-09" />
</svg>
</div>
<!-- SVG -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 22" id="icon-01">
<path
d="M18.29,5.76l-.7-1.37A2.59,2.59,0,0,0,15.29,3H10.71a2.59,2.59,0,0,0-2.3,1.39l-.7,1.37a2.6,2.6,0,0,1-2.3,1.39H3.58A2.57,2.57,0,0,0,1,9.71V20.44A2.57,2.57,0,0,0,3.58,23H22.42A2.57,2.57,0,0,0,25,20.44V9.71a2.57,2.57,0,0,0-2.58-2.56H20.59A2.6,2.6,0,0,1,18.29,5.76Z"
transform="translate(0 -2)"
/>
<ellipse cx="13" cy="12.99" rx="4.52" ry="4.49" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 22" id="icon-02">
<line x1="25" y1="12.58" x2="25" y2="9.42" />
<line x1="21" y1="14.16" x2="21" y2="7.84" />
<line x1="17" y1="15.74" x2="17" y2="6.26" />
<line x1="13" y1="21" x2="13" y2="1" />
<line x1="9" y1="17.32" x2="9" y2="4.68" />
<line x1="5" y1="13.63" x2="5" y2="8.37" />
<line x1="1" y1="11.53" x2="1" y2="10.47" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 26 22" id="icon-03">
<polygon points="8.08 10 1 21 25 21 18.09 12.66 13.78 17.45 8.08 10" />
<circle cx="8" cy="4" r="3" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-01">
<polygon
stroke="var(--shape-color-03)"
points="155.77 140.06 141.08 152.42 159.12 158.96 155.77 140.06"
/>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-02">
<g stroke="var(--shape-color-02)">
<line x1="158.66" y1="146.73" x2="141.54" y2="152.29" />
<line x1="147.32" y1="140.95" x2="152.88" y2="158.07" />
</g>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-03">
<circle stroke="var(--shape-color-01)" cx="150.1" cy="149.51" r="13" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-04">
<circle fill="var(--shape-color-01)" cx="150.1" cy="149.51" r="4" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-05">
<rect
stroke="var(--shape-color-03)"
x="141.1"
y="140.51"
width="18"
height="18"
transform="translate(40.44 -31.76) rotate(13.94)"
/>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-06">
<g stroke="var(--shape-color-02)">
<line x1="158.48" y1="152.78" x2="141.72" y2="146.24" />
<line x1="153.37" y1="141.13" x2="146.83" y2="157.89" />
</g>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-07">
<rect
stroke="var(--shape-color-03)"
x="138.1"
y="137.51"
width="24"
height="24"
transform="translate(-42.94 62.23) rotate(-20.56)"
/>
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-08">
<circle fill="var(--shape-color-01)" cx="150.1" cy="149.51" r="4" />
</symbol>
<symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300" id="shape-09">
<circle stroke="var(--shape-color-01)" cx="150.1" cy="149.51" r="8" />
</symbol>
</svg>
</template>
<style lang="scss" scoped>
.wrapper {
--background: #62abff;
--icon-color: #414856;
--shape-color-01: #b8cbee;
--shape-color-02: #7691e8;
--shape-color-03: #fdd053;
--width: 90px;
--height: 90px;
--border-radius: var(--height);
width: var(--width);
height: var(--height);
position: relative;
border-radius: var(--border-radius);
display: flex;
justify-content: center;
align-items: center;
.btn {
background: var(--background);
width: var(--width);
height: var(--height);
position: relative;
z-index: 3;
border-radius: var(--border-radius);
box-shadow: 0 10px 30px rgba(#414856, 0.05);
display: flex;
justify-content: center;
align-items: center;
animation: plus-animation-reverse 0.5s ease-out forwards;
&::before,
&::after {
content: '';
display: block;
position: absolute;
border-radius: 4px;
background: #fff;
}
&::before {
width: 4px;
height: 28px;
}
&::after {
width: 28px;
height: 4px;
}
}
.tooltip {
width: 90px;
height: 75px;
border-radius: 70px;
position: absolute;
background: #fff;
z-index: 2;
padding: 0 15px;
box-shadow: 0 10px 30px rgba(#414856, 0.05);
opacity: 0;
top: 0;
display: flex;
justify-content: space-around;
align-items: center;
transition: opacity 0.15s ease-in, top 0.15s ease-in, width 0.15s ease-in;
> svg {
width: 100%;
height: 26px;
display: flex;
justify-content: space-around;
align-items: center;
cursor: pointer;
.icon {
fill: none;
stroke: var(--icon-color);
stroke-width: 2px;
stroke-linecap: round;
stroke-linejoin: round;
opacity: 0.4;
transition: opacity 0.3s ease;
}
&:hover {
.icon {
opacity: 1;
}
}
}
&::after {
content: '';
width: 20px;
height: 20px;
background: #fff;
border-radius: 3px;
position: absolute;
left: 50%;
margin-left: -10px;
bottom: -8px;
transform: rotate(45deg);
z-index: 0;
}
}
> svg {
width: 300px;
height: 300px;
position: absolute;
z-index: 1;
transform: scale(0);
.shape {
fill: none;
stroke: none;
stroke-width: 3px;
stroke-linecap: round;
stroke-linejoin: round;
transform-origin: 50% 20%;
}
}
input {
height: 100%;
width: 100%;
border-radius: var(--border-radius);
cursor: pointer;
position: absolute;
z-index: 5;
opacity: 0;
&:checked {
~ svg {
animation: pang-animation 1.2s ease-out forwards;
.shape {
@for $shape from 1 through 9 {
&:nth-of-type(#{$shape}) {
transform: translate(random(50) - 25 + px, 30%) rotate(40deg * $shape);
}
}
}
}
~ .btn {
animation: plus-animation 0.5s ease-out forwards;
}
~ .tooltip {
width: 190px;
height: 70px;
animation: stretch-animation 1s ease-out forwards 0.15s;
top: -90px;
opacity: 1;
}
}
}
}
@keyframes pang-animation {
0% {
transform: scale(0);
opacity: 0;
}
40% {
transform: scale(1);
opacity: 1;
}
100% {
transform: scale(1.1);
opacity: 0;
}
}
@keyframes plus-animation {
0% {
transform: rotate(0) scale(1);
}
20% {
transform: rotate(60deg) scale(0.93);
}
55% {
transform: rotate(35deg) scale(0.97);
}
80% {
transform: rotate(48deg) scale(0.94);
}
100% {
transform: rotate(45deg) scale(0.95);
}
}
@keyframes plus-animation-reverse {
0% {
transform: rotate(45deg) scale(0.95);
}
20% {
transform: rotate(-15deg);
}
55% {
transform: rotate(10deg);
}
80% {
transform: rotate(-3deg);
}
100% {
transform: rotate(0) scale(1);
}
}
@keyframes stretch-animation {
0% {
transform: scale(1, 1);
}
10% {
transform: scale(1.1, 0.9);
}
30% {
transform: scale(0.9, 1.1);
}
50% {
transform: scale(1.05, 0.95);
}
100% {
transform: scale(1, 1);
}
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<div class="tooltip__container">
<div
:class="[
'tooltip',
{ 'cooltipz--static': $props.disableAnimation },
{ 'cooltipz--visible': $props.alwaysVisible },
]"
:aria-label="$props.tooltip"
:data-cooltipz-dir="$props.position"
:data-cooltipz-size="$props.size"
>
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
props: {
tooltip: { type: String, default: 'Hello world!' },
position: { type: String, default: 'top' }, // bottom-right bottom...
size: { type: String, default: 'default' }, // small medium large fit
disableAnimation: { type: Boolean, default: false },
alwaysVisible: { type: Boolean, default: false },
},
})
</script>
<style lang="scss" scoped>
@use 'cooltipz-css/src/cooltipz';
.tooltip__container {
width: 100%;
height: 100%;
}
[aria-label][data-cooltipz-dir]::after,
[aria-label][class*='cooltipz']::after {
font-family: Verdana, Geneva, Tahoma, 'Font Awesome 5 Free', 'Font Awesome 5 Brands',
var(--cooltipz-fontawesome, Arial), sans-serif;
}
</style>

View File

@ -0,0 +1,14 @@
<template>
<div class="tooltip__container">
<div class="button__wrapper">
<div class="slot__wrapper">
<slot name="button"></slot>
</div>
</div>
<div class="tooltip__wrapper">
<div class="slot__wrapper">
<slot name="tooltip"></slot>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,71 @@
<template>
<div class="tooltip__container">
<div class="tooltip" :ref="setTooltipRef">
<slot></slot>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, watch, onMounted } from 'vue'
import { useElementRef } from '@/hooks'
import useTippy from '@/hooks/lib/useTippy'
export default defineComponent({
props: {
// https://atomiks.github.io/tippyjs/v6/all-props
content: { type: [String, Object, Function], default: 'Hello World!' },
allowHTML: { type: Boolean, default: false },
animateFill: { type: Boolean, default: false },
animation: { type: String, default: 'fade' },
appendTo: { type: [String, Object, Function], default: () => document.body },
aria: {
type: Object,
default: () => {
return {
content: 'auto',
expanded: 'auto',
}
},
},
arrow: { type: [String, Object, Boolean], default: true },
delay: { type: [Number, Array], default: 0 },
duration: { type: [Number, Array], default: 0 },
followCursor: { type: [Boolean, String], default: false },
getReferenceClientRect: { type: Function },
hideOnClick: { type: [Boolean, String], default: true },
plugins: { type: Array, default: () => [] },
// TODO: much more props... continue: ignoreAttributes
},
setup(props) {
const [tooltipRef, setTooltipRef] = useElementRef()
const opts: Parameters<typeof useTippy>[1] = {
content: props.content,
allowHTML: props.allowHTML,
appendTo: props.appendTo,
aria: props.aria,
arrow: props.arrow,
delay: props.delay as any,
duration: props.duration as any,
getReferenceClientRect: (props.getReferenceClientRect ?? null) as any,
hideOnClick: props.hideOnClick as any,
}
if (props.animateFill) opts['animateFill'] = props.animateFill
if (props.plugins) opts['plugins'] = props.plugins as any
if (props.followCursor) opts['followCursor'] = props.followCursor as any
const tippy = useTippy(tooltipRef, opts)
return { setTooltipRef }
},
})
</script>
<style lang="scss" scoped>
.tooltip__container {
width: 100%;
height: 100%;
}
</style>

View File

@ -13,6 +13,7 @@ import useTypewriterEffect from './useTypewriterEffect'
import useIntervalWatcher from './useIntervalWatcher' import useIntervalWatcher from './useIntervalWatcher'
import useKeepAliveWindowScrollTop from './useKeepAliveWindowScrollTop' import useKeepAliveWindowScrollTop from './useKeepAliveWindowScrollTop'
import useWindowScrollLock from './useWindowScrollLock' import useWindowScrollLock from './useWindowScrollLock'
import useScrollToElement from './useScrollToElement'
export { export {
useState, useState,
@ -37,4 +38,5 @@ export {
useIntervalWatcher, useIntervalWatcher,
useKeepAliveWindowScrollTop, useKeepAliveWindowScrollTop,
useWindowScrollLock, useWindowScrollLock,
useScrollToElement,
} }

28
src/hooks/lib/useTippy.ts Normal file
View File

@ -0,0 +1,28 @@
import { ref, Ref, watch, onBeforeUnmount } from 'vue'
import tippy from 'tippy.js'
import 'tippy.js/dist/tippy.css'
const useTippy = <El>(
elementRef: El extends Element ? Element : Ref<Element | null>,
optionalProps?: Parameters<typeof tippy>[1]
) => {
const tippyRef: Ref<ReturnType<typeof tippy> | []> = ref([])
if (elementRef instanceof Element) {
tippyRef.value = [tippy(elementRef, optionalProps)]
} else {
watch(elementRef, (element) => {
if (element) {
tippyRef.value = [tippy(element, optionalProps)]
}
})
}
onBeforeUnmount(() => {
tippyRef.value[0]?.destroy()
})
return tippyRef.value[0] ?? null
}
export default useTippy

View File

@ -1,5 +1,5 @@
import { onMounted, onUnmounted, onActivated, onDeactivated } from 'vue' import { onMounted, onUnmounted, onActivated, onDeactivated } from 'vue'
export default function useIntervalWatcher(func: () => void, interval = 100): void { const useIntervalWatcher = (func: () => void, interval = 100): void => {
let timer = NaN let timer = NaN
const addWatcher = () => { const addWatcher = () => {
if (timer) return if (timer) return
@ -16,3 +16,5 @@ export default function useIntervalWatcher(func: () => void, interval = 100): vo
onUnmounted(() => removeWatcher()) onUnmounted(() => removeWatcher())
onDeactivated(() => removeWatcher()) onDeactivated(() => removeWatcher())
} }
export default useIntervalWatcher

View File

@ -3,7 +3,7 @@ import { useWindowScroll } from '@vueuse/core'
import { useState } from '@/hooks' import { useState } from '@/hooks'
export default function () { export default function () {
const { scrollTop, scrollLeft } = (function () { const { scrollTop } = (function () {
const { x, y } = useWindowScroll() const { x, y } = useWindowScroll()
return { scrollTop: y, scrollLeft: x } return { scrollTop: y, scrollLeft: x }
})() })()
@ -18,8 +18,8 @@ export default function () {
onActivated(() => { onActivated(() => {
window.scrollTo({ window.scrollTo({
top: scrollLeft.value ?? 0, top: scrollTopCache.value ?? 0,
behavior: 'smooth', behavior: 'auto',
}) })
// window.scrollTo(scrollLeft.value ?? 0, scrollTopCache.value) // window.scrollTo(scrollLeft.value ?? 0, scrollTopCache.value)
setIsScrollTopSet(true) setIsScrollTopSet(true)

View File

@ -1,18 +1,18 @@
import { ref, Ref, watch, onMounted, onUnmounted } from 'vue' import { ref, Ref } from 'vue'
// I'm not sure if this influent performence? import useIntervalWatcher from './useIntervalWatcher'
export default function <El>(elementRef: El extends Element ? Element : Ref<Element | null>) {
export default function <El>(
elementRef: El extends HTMLElement ? HTMLElement : Ref<HTMLElement | null>
) {
const offset = ref({ const offset = ref({
offsetTop: NaN, offsetTop: NaN,
offsetLeft: NaN, offsetLeft: NaN,
}) })
let timer: number useIntervalWatcher(() => {
onMounted(() => {
timer = window.setInterval(() => {
let element: HTMLElement let element: HTMLElement
if (elementRef instanceof Element) { if (elementRef instanceof HTMLElement) {
element = elementRef as HTMLElement element = elementRef
} else { } else {
if (!elementRef.value) return if (!elementRef.value) return
element = elementRef.value as HTMLElement element = elementRef.value as HTMLElement
@ -21,10 +21,7 @@ export default function <El>(elementRef: El extends Element ? Element : Ref<Elem
offsetTop: element.offsetTop, offsetTop: element.offsetTop,
offsetLeft: element.offsetLeft, offsetLeft: element.offsetLeft,
} }
}, 100)
}) })
onUnmounted(() => clearInterval(timer))
return offset return offset
} }

View File

@ -0,0 +1,74 @@
import { computed, ref } from 'vue'
import type { Ref } from 'vue'
import useOffsetDistance from './useOffsetDistance'
import useResizeObserver from './useResizeObserver'
import useWindowResize from './useWindowResize'
/**
* @param elementRef HTMLElement
* @param trigger the position of element: 'top' | 'bottom' | percentage (0~1)
* @param to the position of window: 'top' | 'bottom' | percentage (0~1)
* @returns void
*/
const useScrollToElement = <El>(
elementRef: El extends HTMLElement ? HTMLElement : Ref<HTMLElement | null>,
trigger: 'top' | 'bottom' | number | string = 'top',
to: 'top' | 'bottom' | number | string = 'top'
) => {
const offset = useOffsetDistance(elementRef)
const size = useResizeObserver(elementRef as Ref<Element>)
const windowSize = useWindowResize()
const target = computed((): number => {
if (trigger === 'top') {
return offset.value.offsetTop
} else if (trigger === 'bottom') {
return offset.value.offsetTop + size.value.height + size.value.paddingTop
} else if (typeof trigger === 'number') {
return offset.value.offsetTop + size.value.height * trigger + size.value.paddingTop
} else if (typeof trigger === 'string') {
return offset.value.offsetTop + Number(trigger.replace('px', '')) + size.value.paddingTop
} else {
return NaN
}
})
const transform = computed(() => {
if (to === 'top') {
return 0
} else if (to === 'bottom') {
return windowSize.value.innerHeight
} else if (typeof to === 'number') {
return windowSize.value.innerHeight * to
} else if (typeof to === 'string') {
return Number(to.replace('px', ''))
} else {
return NaN
}
})
const final = computed((): { offset: number; transform: number } => {
return { offset: target.value, transform: transform.value }
})
const pending = ref(false)
const scrollTrigger = () => {
pending.value = true
let timer = window.setInterval(() => {
if (!isNaN(final.value.offset) && !isNaN(final.value.transform)) {
if (!pending.value) return
window.scrollTo({
top: final.value.offset - final.value.transform,
behavior: 'smooth',
})
pending.value = false
window.clearInterval(timer)
}
}, 100)
}
return scrollTrigger
}
export default useScrollToElement

View File

@ -13,6 +13,7 @@
</footer> </footer>
</section> </section>
</div> </div>
<!-- / PC -->
<!-- Mobile --> <!-- Mobile -->
<div v-else :class="['page', 'mobile', { 'show-drawer': shouldDrawerOpen }]"> <div v-else :class="['page', 'mobile', { 'show-drawer': shouldDrawerOpen }]">
<header class="header__wrapper"> <header class="header__wrapper">
@ -31,6 +32,10 @@
<NavDrawer></NavDrawer> <NavDrawer></NavDrawer>
</aside> </aside>
</div> </div>
<!-- / Mobile -->
<div class="go-top__wrapper">
<GoTop :showDrawer="shouldDrawerOpen"></GoTop>
</div>
</div> </div>
</template> </template>
@ -47,10 +52,11 @@ import Header from '@/layouts/components/header/Header.vue'
import Footer from '@/layouts/components/footer/Footer.vue' import Footer from '@/layouts/components/footer/Footer.vue'
import HeaderMobile from '@/layouts/components/header/HeaderMobile.vue' import HeaderMobile from '@/layouts/components/header/HeaderMobile.vue'
import NavDrawer from '@/layouts/components/header/NavDrawer.vue' import NavDrawer from '@/layouts/components/header/NavDrawer.vue'
import GoTop from './components/goTop/GoTop.vue'
export default defineComponent({ export default defineComponent({
name: 'LayoutBase', name: 'LayoutBase',
components: { Header, Footer, HeaderMobile, NavDrawer }, components: { Header, Footer, HeaderMobile, NavDrawer, GoTop },
props: { headerPlaceholder: { type: Boolean, default: true } }, props: { headerPlaceholder: { type: Boolean, default: true } },
setup() { setup() {
useKeepAliveWindowScrollTop() useKeepAliveWindowScrollTop()
@ -190,4 +196,7 @@ $drawer-width: 260px;
} }
} }
} }
.go-top__wrapper {
--drawer-width: #{$drawer-width};
}
</style> </style>

View File

@ -0,0 +1,90 @@
<template>
<div
class="go-top__container mdc-card mdc-elevation--z4"
:data-hide="scrollTop < 200"
:data-move-side="shouldShowDrawer"
@click="handleGoTopEvent"
>
<Ripple>
<div class="content">
<div class="icon"><i class="fas fa-arrow-up"></i></div>
<div class="progress">{{ progress }}%</div>
</div>
</Ripple>
</div>
</template>
<script lang="ts">
import { defineComponent, computed, watch, ref } from 'vue'
import { useWindowScroll } from '@vueuse/core'
import { useWindowResize, useResizeObserver } from '@/hooks'
import Ripple from '@/components/ripple/Ripple.vue'
export default defineComponent({
components: { Ripple },
props: {
showDrawer: { type: Boolean, default: false },
},
setup(props) {
const { y } = useWindowScroll()
const windowSize = useWindowResize()
// @ts-ignore
const documentSize = useResizeObserver(document.body)
const progress = computed(() => {
const p = Math.floor(
(y.value / (documentSize.value.height - windowSize.value.innerHeight)) * 100
)
return isNaN(p) ? 0 : p
})
const shouldShowDrawer = ref(false)
watch(
() => props.showDrawer,
(state) => (shouldShowDrawer.value = state),
{ immediate: true }
)
const handleGoTopEvent = () =>
window.scrollTo({
top: 0,
behavior: 'smooth',
})
return { progress, scrollTop: y, shouldShowDrawer, handleGoTopEvent }
},
})
</script>
<style lang="scss" scoped>
.go-top__container {
position: fixed;
z-index: 1;
bottom: 24px;
right: 24px;
width: 36px;
height: 36px;
opacity: 1;
transition: all 0.5s;
overflow: hidden;
user-select: none;
cursor: pointer;
.content {
width: 100%;
height: 100%;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
// .icon{}
.progress {
font-size: 12px;
}
}
&[data-hide='true'] {
opacity: 0;
pointer-events: none;
}
&[data-move-side='true'] {
transform: translate3d(var(--drawer-width, 260px), 0, 0);
}
}
</style>

View File

@ -1,8 +1,8 @@
<template> <template>
<Link class="link__container" :url="$props.url"> <Link class="link__container" :url="$props.url">
<div class="nav-item__container mdc-list-item" :ref="setContainerRef"> <div class="nav-item__container">
<div class="mdc-list-item__ripple"></div> <Ripple>
<span class="nav-item__content mdc-list-item__text"> <span class="nav-item__content">
<span class="icon icon--prefix" v-if="prefix"> <span class="icon icon--prefix" v-if="prefix">
<i :class="prefix"></i> <i :class="prefix"></i>
</span> </span>
@ -11,37 +11,23 @@
<i :class="suffix"></i> <i :class="suffix"></i>
</span> </span>
</span> </span>
</Ripple>
</div> </div>
</Link> </Link>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import { useMDCRipple, useRouter, useElementRef } from '@/hooks' import Ripple from '@/components/ripple/Ripple.vue'
import linkHandler from '@/utils/linkHandler'
export default defineComponent({ export default defineComponent({
name: 'NavItem', components: { Ripple },
props: { props: {
prefix: String, prefix: String,
suffix: String, suffix: String,
context: String, context: String,
url: String, url: String,
}, },
setup(props) {
const [containerRef, setContainerRef] = useElementRef()
useMDCRipple(containerRef)
const router = useRouter()
const handleClickEvent = () => {
if (props.url) {
linkHandler.handleClickLink({ url: props.url, router, target: '_blank' })
}
}
return { setContainerRef, handleClickEvent }
},
}) })
</script> </script>
@ -59,13 +45,12 @@ export default defineComponent({
padding-right: 0; padding-right: 0;
} }
.nav-item__content { .nav-item__content {
width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
flex-flow: row nowrap; flex-flow: row nowrap;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 0 24px; margin: 0 24px;
span { span {
color: #5f6368; color: #5f6368;
font-weight: 500; font-weight: 500;

View File

@ -1,6 +1,10 @@
import { createApp } from 'vue' import { createApp } from 'vue'
import { VueSvgIconPlugin } from '@yzfe/vue3-svgicon' import { VueSvgIconPlugin } from '@yzfe/vue3-svgicon'
import '@yzfe/svgicon/lib/svgicon.css' import '@yzfe/svgicon/lib/svgicon.css'
import VueTippy from 'vue-tippy'
import 'tippy.js/dist/tippy.css'
import 'tippy.js/animations/scale.css'
import 'tippy.js/themes/material.css'
import 'animate.css/animate.css' import 'animate.css/animate.css'
import App from './App.vue' import App from './App.vue'
import router from './router' import router from './router'
@ -22,4 +26,5 @@ app.use(VueSvgIconPlugin, { tagName: 'svg-icon' })
app.component('UiIcon', UiIcon) app.component('UiIcon', UiIcon)
app.component('Image', Image) app.component('Image', Image)
app.component('Link', Link) app.component('Link', Link)
app.use(VueTippy, { directive: 'tippy', component: 'tippy', componentSingleton: 'tippy-singleton' })
app.mount('#app') app.mount('#app')

View File

@ -1,16 +1,20 @@
import { Ref } from 'vue' import { Ref } from 'vue'
import { useState, usePersistedState } from '@/hooks' import { useState, usePersistedState } from '@/hooks'
import type { MessageOptions } from '@/store/messages'
import { AxiosResponse } from 'axios' // interface import { AxiosResponse } from 'axios' // interface
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import API from '@/api' import API from '@/api'
import { GetCommentParams } from '@/api/Wp/v2' // interface import { GetCommentParams } from '@/api/Wp/v2' // interface
import { getPagination } from '@/utils/filters/paginationFilter' import { getPagination } from '@/utils/filters/paginationFilter'
import logger from '@/utils/logger' import logger from '@/utils/logger'
import axiosErrorHandler from '@/utils/axiosErrorHandler'
import intl from '@/locales'
interface FetchParams { interface FetchParams {
state: Ref<CommentStore> state: Ref<CommentStore>
namespace: string namespace: string
opts: GetCommentParams opts: GetCommentParams
addMessage: (options: MessageOptions) => void
} }
export default function comments(): object { export default function comments(): object {
@ -46,7 +50,7 @@ export default function comments(): object {
setCommentStore(stateCopy) setCommentStore(stateCopy)
} }
const fetchComment = async ({ state, namespace, opts }: FetchParams) => { const fetchComment = async ({ state, namespace, opts, addMessage }: FetchParams) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
API.Wp.v2 API.Wp.v2
.getComments(opts as GetCommentParams) .getComments(opts as GetCommentParams)
@ -56,6 +60,12 @@ export default function comments(): object {
}) })
.catch((error) => { .catch((error) => {
logger('error', error) logger('error', error)
const errorMsgTitle = intl.formatMessage({
id: 'messages.posts.fetchPostError',
defaultMessage: 'Failed to fetch post content.',
})
const errorMsg = axiosErrorHandler(error).msg
addMessage({ type: 'error', title: errorMsgTitle, detail: errorMsg, closeTimeout: 0 })
reject(error) reject(error)
}) })
}) })

View File

@ -6,4 +6,9 @@
text-decoration: none; text-decoration: none;
color: inherit; color: inherit;
} }
.tippy-box {
a {
text-decoration: underline;
}
}
} }

View File

@ -8,3 +8,4 @@
// @import '@material/textfield/mdc-text-field'; // @import '@material/textfield/mdc-text-field';
// @import '@material/dialog/mdc-dialog'; // @import '@material/dialog/mdc-dialog';
// @import '@material/typography/styles'; // @import '@material/typography/styles';
@use '@material/switch/styles';

660
yarn.lock
View File

@ -728,420 +728,420 @@
"@types/yargs" "^16.0.0" "@types/yargs" "^16.0.0"
chalk "^4.0.0" chalk "^4.0.0"
"@material/animation@13.0.0-canary.5981207f7.0": "@material/animation@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/animation/download/@material/animation-13.0.0-canary.5981207f7.0.tgz#5b374aaa84686d5a4e08fc7c6bc685362e6fd970" resolved "https://registry.nlark.com/@material/animation/download/@material/animation-13.0.0-canary.b47dd37a6.0.tgz#ba8e69d986857c22f8fa1a0f412832bd9f6a2f27"
integrity sha1-WzdKqoRobVpOCPx8a8aFNi5v2XA= integrity sha1-uo5p2YaFfCL4+hoPQSgyvZ9qLyc=
dependencies: dependencies:
tslib "^2.1.0" tslib "^2.1.0"
"@material/base@13.0.0-canary.5981207f7.0": "@material/base@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/base/download/@material/base-13.0.0-canary.5981207f7.0.tgz#2613917ee525385820c6be3f18a65ff00f6239a5" resolved "https://registry.nlark.com/@material/base/download/@material/base-13.0.0-canary.b47dd37a6.0.tgz#f76e858dc9aecad5115f93254a5bf474e7ee22c7"
integrity sha1-JhORfuUlOFggxr4/GKZf8A9iOaU= integrity sha1-926FjcmuytURX5MlSlv0dOfuIsc=
dependencies: dependencies:
tslib "^2.1.0" tslib "^2.1.0"
"@material/button@13.0.0-canary.5981207f7.0", "@material/button@^13.0.0-canary.5981207f7.0": "@material/button@13.0.0-canary.b47dd37a6.0", "@material/button@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/button/download/@material/button-13.0.0-canary.5981207f7.0.tgz#8ca3ef5256ef57c4a21e08200cd07d5a4073deea" resolved "https://registry.nlark.com/@material/button/download/@material/button-13.0.0-canary.b47dd37a6.0.tgz#d16f319cd7fe4f702d0946ac49ec9bfebfe04429"
integrity sha1-jKPvUlbvV8SiHgggDNB9WkBz3uo= integrity sha1-0W8xnNf+T3AtCUasSeyb/r/gRCk=
dependencies: dependencies:
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/tokens" "13.0.0-canary.5981207f7.0" "@material/tokens" "13.0.0-canary.b47dd37a6.0"
"@material/touch-target" "13.0.0-canary.5981207f7.0" "@material/touch-target" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/card@^13.0.0-canary.5981207f7.0": "@material/card@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/card/download/@material/card-13.0.0-canary.5981207f7.0.tgz#ec29db9f5a00931886ca2c939e74dcc3a1375c52" resolved "https://registry.nlark.com/@material/card/download/@material/card-13.0.0-canary.b47dd37a6.0.tgz#892acad42abd7a81506c371216fbcef62aec5ab3"
integrity sha1-7Cnbn1oAkxiGyiyTnnTcw6E3XFI= integrity sha1-iSrK1Cq9eoFQbDcSFvvO9irsWrM=
dependencies: dependencies:
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/checkbox@13.0.0-canary.5981207f7.0", "@material/checkbox@^13.0.0-canary.5981207f7.0": "@material/checkbox@13.0.0-canary.b47dd37a6.0", "@material/checkbox@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/checkbox/download/@material/checkbox-13.0.0-canary.5981207f7.0.tgz#339e9946f4c8b1e0b477c395e6201a71451ed0d0" resolved "https://registry.nlark.com/@material/checkbox/download/@material/checkbox-13.0.0-canary.b47dd37a6.0.tgz#b929c96ac333fb0e14a3e9cc8c02ca5a36001309"
integrity sha1-M56ZRvTIseC0d8OV5iAacUUe0NA= integrity sha1-uSnJasMz+w4Uo+nMjALKWjYAEwk=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/touch-target" "13.0.0-canary.5981207f7.0" "@material/touch-target" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/chips@^13.0.0-canary.5981207f7.0": "@material/chips@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/chips/download/@material/chips-13.0.0-canary.5981207f7.0.tgz#51d3002ed6d2e7be77104f42a61cc49708e704e5" resolved "https://registry.nlark.com/@material/chips/download/@material/chips-13.0.0-canary.b47dd37a6.0.tgz#20f1cf7f74fa24dfdf2f8105106af622e48dca32"
integrity sha1-UdMALtbS5753EE9CphzElwjnBOU= integrity sha1-IPHPf3T6JN/fL4EFEGr2IuSNyjI=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/checkbox" "13.0.0-canary.5981207f7.0" "@material/checkbox" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/touch-target" "13.0.0-canary.5981207f7.0" "@material/touch-target" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/density@13.0.0-canary.5981207f7.0": "@material/density@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/density/download/@material/density-13.0.0-canary.5981207f7.0.tgz#f25f29465ec287bfc69810eaa5083d780e54e602" resolved "https://registry.nlark.com/@material/density/download/@material/density-13.0.0-canary.b47dd37a6.0.tgz#373dccc3572588dcd4c8a015aedd84007de9c171"
integrity sha1-8l8pRl7Ch7/GmBDqpQg9eA5U5gI= integrity sha1-Nz3Mw1cliNzUyKAVrt2EAH3pwXE=
dependencies: dependencies:
tslib "^2.1.0" tslib "^2.1.0"
"@material/dialog@^13.0.0-canary.5981207f7.0": "@material/dialog@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/dialog/download/@material/dialog-13.0.0-canary.5981207f7.0.tgz#4c67dc14f9af05e9e265d17bf178ba63ae912d81" resolved "https://registry.nlark.com/@material/dialog/download/@material/dialog-13.0.0-canary.b47dd37a6.0.tgz#17b2d0c120de04fc5c7d14b74cc33a240d878e8e"
integrity sha1-TGfcFPmvBeniZdF78Xi6Y66RLYE= integrity sha1-F7LQwSDeBPxcfRS3TMM6JA2Hjo4=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/button" "13.0.0-canary.5981207f7.0" "@material/button" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/icon-button" "13.0.0-canary.5981207f7.0" "@material/icon-button" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/touch-target" "13.0.0-canary.5981207f7.0" "@material/touch-target" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/dom@13.0.0-canary.5981207f7.0": "@material/dom@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/dom/download/@material/dom-13.0.0-canary.5981207f7.0.tgz#05af9f520629ddf8db06a0dcd9ce6a8814117fc8" resolved "https://registry.nlark.com/@material/dom/download/@material/dom-13.0.0-canary.b47dd37a6.0.tgz#7d9fb8641e9c97908a373ab0602390fcc5e4afe6"
integrity sha1-Ba+fUgYp3fjbBqDc2c5qiBQRf8g= integrity sha1-fZ+4ZB6cl5CKNzqwYCOQ/MXkr+Y=
dependencies: dependencies:
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/elevation@13.0.0-canary.5981207f7.0", "@material/elevation@^13.0.0-canary.5981207f7.0": "@material/elevation@13.0.0-canary.b47dd37a6.0", "@material/elevation@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/elevation/download/@material/elevation-13.0.0-canary.5981207f7.0.tgz#5eaf111680d4d886156e43e913cc46a812afffa5" resolved "https://registry.nlark.com/@material/elevation/download/@material/elevation-13.0.0-canary.b47dd37a6.0.tgz#4e79fdea8d15c52383d7b290cfc4f37f9a77fc71"
integrity sha1-Xq8RFoDU2IYVbkPpE8xGqBKv/6U= integrity sha1-Tnn96o0VxSOD17KQz8Tzf5p3/HE=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/feature-targeting@13.0.0-canary.5981207f7.0": "@material/feature-targeting@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/feature-targeting/download/@material/feature-targeting-13.0.0-canary.5981207f7.0.tgz#c9f969e740315cc02fbb2d86c6883dada6286a0d" resolved "https://registry.nlark.com/@material/feature-targeting/download/@material/feature-targeting-13.0.0-canary.b47dd37a6.0.tgz#a0395eb389968ec5d1ab33a1e5b9eba2be1b8b7e"
integrity sha1-yflp50AxXMAvuy2Gxog9raYoag0= integrity sha1-oDles4mWjsXRqzOh5bnror4bi34=
dependencies: dependencies:
tslib "^2.1.0" tslib "^2.1.0"
"@material/floating-label@13.0.0-canary.5981207f7.0": "@material/floating-label@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/floating-label/download/@material/floating-label-13.0.0-canary.5981207f7.0.tgz#19a04841e2068b0996fb2946fdbdf349aa2946c9" resolved "https://registry.nlark.com/@material/floating-label/download/@material/floating-label-13.0.0-canary.b47dd37a6.0.tgz#39b4e85b842356ca1f350f4078c4c6973127799d"
integrity sha1-GaBIQeIGiwmW+ylG/b3zSaopRsk= integrity sha1-ObToW4QjVsofNQ9AeMTGlzEneZ0=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/form-field@^13.0.0-canary.5981207f7.0": "@material/form-field@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/form-field/download/@material/form-field-13.0.0-canary.5981207f7.0.tgz#9bf34aa5c834801d8e1df4a8d126fa7f092bb1e1" resolved "https://registry.nlark.com/@material/form-field/download/@material/form-field-13.0.0-canary.b47dd37a6.0.tgz#30cd62b3ca25c5b770dc014a281760f0e5a9594a"
integrity sha1-m/NKpcg0gB2OHfSo0Sb6fwkrseE= integrity sha1-MM1is8olxbdw3AFKKBdg8OWpWUo=
dependencies: dependencies:
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/icon-button@13.0.0-canary.5981207f7.0": "@material/icon-button@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/icon-button/download/@material/icon-button-13.0.0-canary.5981207f7.0.tgz#7e92c81419c74f26955f3e435758223313d2cabc" resolved "https://registry.nlark.com/@material/icon-button/download/@material/icon-button-13.0.0-canary.b47dd37a6.0.tgz#43f708598547d909a6a856ffa1fa8c0b92a765dc"
integrity sha1-fpLIFBnHTyaVXz5DV1giMxPSyrw= integrity sha1-Q/cIWYVH2QmmqFb/ofqMC5KnZdw=
dependencies: dependencies:
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/touch-target" "13.0.0-canary.5981207f7.0" "@material/touch-target" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/line-ripple@13.0.0-canary.5981207f7.0": "@material/line-ripple@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/line-ripple/download/@material/line-ripple-13.0.0-canary.5981207f7.0.tgz#d1f162625e71b2a072354b28e2f2dfb8eef5bd82" resolved "https://registry.nlark.com/@material/line-ripple/download/@material/line-ripple-13.0.0-canary.b47dd37a6.0.tgz#9ef49e83e28bc947ebb5c97e2bf6587e4fbc0b75"
integrity sha1-0fFiYl5xsqByNUso4vLfuO71vYI= integrity sha1-nvSeg+KLyUfrtcl+K/ZYfk+8C3U=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/list@13.0.0-canary.5981207f7.0": "@material/list@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/list/download/@material/list-13.0.0-canary.5981207f7.0.tgz#be8f0163b29e22c448f8eda0c9a41f12ba32012b" resolved "https://registry.nlark.com/@material/list/download/@material/list-13.0.0-canary.b47dd37a6.0.tgz#0be260768fc9ce8f395322f727e76afbe98d90ac"
integrity sha1-vo8BY7KeIsRI+O2gyaQfEroyASs= integrity sha1-C+Jgdo/Jzo85UyL3J+dq++mNkKw=
dependencies: dependencies:
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/menu-surface@13.0.0-canary.5981207f7.0": "@material/menu-surface@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/menu-surface/download/@material/menu-surface-13.0.0-canary.5981207f7.0.tgz#09ae6cbc513094b05aef9d94a29ec5d61511e97c" resolved "https://registry.nlark.com/@material/menu-surface/download/@material/menu-surface-13.0.0-canary.b47dd37a6.0.tgz#80ae1a67cb0d3a2d054b705b76c3bbd53d370f7b"
integrity sha1-Ca5svFEwlLBa752Uop7F1hUR6Xw= integrity sha1-gK4aZ8sNOi0FS3BbdsO71T03D3s=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/menu@^13.0.0-canary.5981207f7.0": "@material/menu@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/menu/download/@material/menu-13.0.0-canary.5981207f7.0.tgz#e9701d5a0da77255dc1a173be1962c503f462ec9" resolved "https://registry.nlark.com/@material/menu/download/@material/menu-13.0.0-canary.b47dd37a6.0.tgz#48ecd3b6e5887ed4bb07a9fef835bd3bc9d5abb9"
integrity sha1-6XAdWg2nclXcGhc74ZYsUD9GLsk= integrity sha1-SOzTtuWIftS7B6n++DW9O8nVq7k=
dependencies: dependencies:
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/list" "13.0.0-canary.5981207f7.0" "@material/list" "13.0.0-canary.b47dd37a6.0"
"@material/menu-surface" "13.0.0-canary.5981207f7.0" "@material/menu-surface" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/notched-outline@13.0.0-canary.5981207f7.0": "@material/notched-outline@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/notched-outline/download/@material/notched-outline-13.0.0-canary.5981207f7.0.tgz#efbfa8e3a4c9b1fb3e255b61081a2e9664e9f95c" resolved "https://registry.nlark.com/@material/notched-outline/download/@material/notched-outline-13.0.0-canary.b47dd37a6.0.tgz#e133b1c24f3955b8857ebf702446a9c9f4668951"
integrity sha1-77+o46TJsfs+JVthCBoulmTp+Vw= integrity sha1-4TOxwk85VbiFfr9wJEapyfRmiVE=
dependencies: dependencies:
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/floating-label" "13.0.0-canary.5981207f7.0" "@material/floating-label" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/radio@^13.0.0-canary.5981207f7.0": "@material/radio@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/radio/download/@material/radio-13.0.0-canary.5981207f7.0.tgz#e338793e533053f599fe916fe071380131115e51" resolved "https://registry.nlark.com/@material/radio/download/@material/radio-13.0.0-canary.b47dd37a6.0.tgz#0aaf72704da258b8f7e835170e3a5f17fcefeef4"
integrity sha1-4zh5PlMwU/WZ/pFv4HE4ATERXlE= integrity sha1-Cq9ycE2iWLj36DUXDjpfF/zv7vQ=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/touch-target" "13.0.0-canary.5981207f7.0" "@material/touch-target" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/ripple@13.0.0-canary.5981207f7.0", "@material/ripple@^13.0.0-canary.5981207f7.0": "@material/ripple@13.0.0-canary.b47dd37a6.0", "@material/ripple@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/ripple/download/@material/ripple-13.0.0-canary.5981207f7.0.tgz#f27ad7226f67cfe62925ff613b375a7573196023" resolved "https://registry.nlark.com/@material/ripple/download/@material/ripple-13.0.0-canary.b47dd37a6.0.tgz#949521fc1a2a96a170ca5b77efc526e7e92eda1c"
integrity sha1-8nrXIm9nz+YpJf9hOzdadXMZYCM= integrity sha1-lJUh/BoqlqFwylt378Um5+ku2hw=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/rtl@13.0.0-canary.5981207f7.0": "@material/rtl@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/rtl/download/@material/rtl-13.0.0-canary.5981207f7.0.tgz#59dcf1a36eaf791268a97c0636e01edabba0d354" resolved "https://registry.nlark.com/@material/rtl/download/@material/rtl-13.0.0-canary.b47dd37a6.0.tgz#33f4170a4971c25f712e57ca0ff13df0a235b757"
integrity sha1-Wdzxo26veRJoqXwGNuAe2rug01Q= integrity sha1-M/QXCklxwl9xLlfKD/E98KI1t1c=
dependencies: dependencies:
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/shape@13.0.0-canary.5981207f7.0": "@material/shape@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/shape/download/@material/shape-13.0.0-canary.5981207f7.0.tgz#8f5311a1c68b2bb36094716497037fe1b4ed1462" resolved "https://registry.nlark.com/@material/shape/download/@material/shape-13.0.0-canary.b47dd37a6.0.tgz#23a4e70a7d37908a46ba70dc97b0ee988fd07f68"
integrity sha1-j1MRocaLK7NglHFklwN/4bTtFGI= integrity sha1-I6TnCn03kIpGunDcl7DumI/Qf2g=
dependencies: dependencies:
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/switch@^13.0.0-canary.5981207f7.0": "@material/switch@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/switch/download/@material/switch-13.0.0-canary.5981207f7.0.tgz#55cd126d7ffeb77c852ca3599c84c8d2eb1ee620" resolved "https://registry.nlark.com/@material/switch/download/@material/switch-13.0.0-canary.b47dd37a6.0.tgz#6abcde46119a89f7ca0de3aed2a80e0efe687e06"
integrity sha1-Vc0SbX/+t3yFLKNZnITI0use5iA= integrity sha1-arzeRhGaiffKDeOu0qgODv5ofgY=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/tokens" "13.0.0-canary.5981207f7.0" "@material/tokens" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/tab-bar@^13.0.0-canary.5981207f7.0": "@material/tab-bar@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/tab-bar/download/@material/tab-bar-13.0.0-canary.5981207f7.0.tgz#e5b933d53bda1a8bf391b27e126291c3db3efe72" resolved "https://registry.nlark.com/@material/tab-bar/download/@material/tab-bar-13.0.0-canary.b47dd37a6.0.tgz#b8d6d289ab9c0cb7e9df69e75c2947f6c1e8b460"
integrity sha1-5bkz1TvaGovzkbJ+EmKRw9s+/nI= integrity sha1-uNbSiaucDLfp32nnXClH9sHotGA=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/tab" "13.0.0-canary.5981207f7.0" "@material/tab" "13.0.0-canary.b47dd37a6.0"
"@material/tab-indicator" "13.0.0-canary.5981207f7.0" "@material/tab-indicator" "13.0.0-canary.b47dd37a6.0"
"@material/tab-scroller" "13.0.0-canary.5981207f7.0" "@material/tab-scroller" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/tab-indicator@13.0.0-canary.5981207f7.0": "@material/tab-indicator@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/tab-indicator/download/@material/tab-indicator-13.0.0-canary.5981207f7.0.tgz#7d845bb2b4d183adc4c3f94e47cf1e2d9914fb8e" resolved "https://registry.nlark.com/@material/tab-indicator/download/@material/tab-indicator-13.0.0-canary.b47dd37a6.0.tgz#c1399a97872993424dc71723d0b0f889e7f58f36"
integrity sha1-fYRbsrTRg63Ew/lOR88eLZkU+44= integrity sha1-wTmal4cpk0JNxxcj0LD4ief1jzY=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/tab-scroller@13.0.0-canary.5981207f7.0": "@material/tab-scroller@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/tab-scroller/download/@material/tab-scroller-13.0.0-canary.5981207f7.0.tgz#fa0bde574201583b37e55b014e250b6447b70e4a" resolved "https://registry.nlark.com/@material/tab-scroller/download/@material/tab-scroller-13.0.0-canary.b47dd37a6.0.tgz#d190c9e4a062cc7942b911e0184ef41d5456dee1"
integrity sha1-+gveV0IBWDs35VsBTiULZEe3Dko= integrity sha1-0ZDJ5KBizHlCuRHgGE70HVRW3uE=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/tab" "13.0.0-canary.5981207f7.0" "@material/tab" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/tab@13.0.0-canary.5981207f7.0": "@material/tab@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/tab/download/@material/tab-13.0.0-canary.5981207f7.0.tgz#dd237e7097f6417eea2e43f7915ac50d952e3bba" resolved "https://registry.nlark.com/@material/tab/download/@material/tab-13.0.0-canary.b47dd37a6.0.tgz#f99a8175bf0e5ef4d2066368eb6bb25c792dd8ee"
integrity sha1-3SN+cJf2QX7qLkP3kVrFDZUuO7o= integrity sha1-+ZqBdb8OXvTSBmNo62uyXHkt2O4=
dependencies: dependencies:
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/tab-indicator" "13.0.0-canary.5981207f7.0" "@material/tab-indicator" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/textfield@^13.0.0-canary.5981207f7.0": "@material/textfield@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/textfield/download/@material/textfield-13.0.0-canary.5981207f7.0.tgz#e20cf24b62201c273b2cba64411a5a61207131aa" resolved "https://registry.nlark.com/@material/textfield/download/@material/textfield-13.0.0-canary.b47dd37a6.0.tgz#ade5f91f0c272b6a1cec505f8c356249c5a99921"
integrity sha1-4gzyS2IgHCc7LLpkQRpaYSBxMao= integrity sha1-reX5HwwnK2oc7FBfjDViScWpmSE=
dependencies: dependencies:
"@material/animation" "13.0.0-canary.5981207f7.0" "@material/animation" "13.0.0-canary.b47dd37a6.0"
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/density" "13.0.0-canary.5981207f7.0" "@material/density" "13.0.0-canary.b47dd37a6.0"
"@material/dom" "13.0.0-canary.5981207f7.0" "@material/dom" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/floating-label" "13.0.0-canary.5981207f7.0" "@material/floating-label" "13.0.0-canary.b47dd37a6.0"
"@material/line-ripple" "13.0.0-canary.5981207f7.0" "@material/line-ripple" "13.0.0-canary.b47dd37a6.0"
"@material/notched-outline" "13.0.0-canary.5981207f7.0" "@material/notched-outline" "13.0.0-canary.b47dd37a6.0"
"@material/ripple" "13.0.0-canary.5981207f7.0" "@material/ripple" "13.0.0-canary.b47dd37a6.0"
"@material/rtl" "13.0.0-canary.5981207f7.0" "@material/rtl" "13.0.0-canary.b47dd37a6.0"
"@material/shape" "13.0.0-canary.5981207f7.0" "@material/shape" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
"@material/typography" "13.0.0-canary.5981207f7.0" "@material/typography" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/theme@13.0.0-canary.5981207f7.0", "@material/theme@^13.0.0-canary.5981207f7.0": "@material/theme@13.0.0-canary.b47dd37a6.0", "@material/theme@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/theme/download/@material/theme-13.0.0-canary.5981207f7.0.tgz#6f19075b516b0c1e708ece7eeb0e9415e65082d8" resolved "https://registry.nlark.com/@material/theme/download/@material/theme-13.0.0-canary.b47dd37a6.0.tgz#16f15b14086d5bbd5db37fe53c676628af4df238"
integrity sha1-bxkHW1FrDB5wjs5+6w6UFeZQgtg= integrity sha1-FvFbFAhtW71ds3/lPGdmKK9N8jg=
dependencies: dependencies:
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/tokens@13.0.0-canary.5981207f7.0": "@material/tokens@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/tokens/download/@material/tokens-13.0.0-canary.5981207f7.0.tgz#1040b347f87a47ed61207999ab4f7f8d41546fae" resolved "https://registry.nlark.com/@material/tokens/download/@material/tokens-13.0.0-canary.b47dd37a6.0.tgz#32dfc811e18ca144b95f0e48997922838641e99b"
integrity sha1-EECzR/h6R+1hIHmZq09/jUFUb64= integrity sha1-Mt/IEeGMoUS5Xw5ImXkig4ZB6Zs=
dependencies: dependencies:
"@material/elevation" "13.0.0-canary.5981207f7.0" "@material/elevation" "13.0.0-canary.b47dd37a6.0"
"@material/touch-target@13.0.0-canary.5981207f7.0": "@material/touch-target@13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/touch-target/download/@material/touch-target-13.0.0-canary.5981207f7.0.tgz#369f76487ef7bd72eead14eca85f0fb0d39d792a" resolved "https://registry.nlark.com/@material/touch-target/download/@material/touch-target-13.0.0-canary.b47dd37a6.0.tgz#e70d949c42e23b97b88ff97b8b8e4c2999a7e22a"
integrity sha1-Np92SH73vXLurRTsqF8PsNOdeSo= integrity sha1-5w2UnELiO5e4j/l7i45MKZmn4io=
dependencies: dependencies:
"@material/base" "13.0.0-canary.5981207f7.0" "@material/base" "13.0.0-canary.b47dd37a6.0"
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@material/typography@13.0.0-canary.5981207f7.0", "@material/typography@^13.0.0-canary.5981207f7.0": "@material/typography@13.0.0-canary.b47dd37a6.0", "@material/typography@^13.0.0-canary.b47dd37a6.0":
version "13.0.0-canary.5981207f7.0" version "13.0.0-canary.b47dd37a6.0"
resolved "https://registry.nlark.com/@material/typography/download/@material/typography-13.0.0-canary.5981207f7.0.tgz#213c00d2bfb7ffedbb081381a418468ca470b618" resolved "https://registry.nlark.com/@material/typography/download/@material/typography-13.0.0-canary.b47dd37a6.0.tgz#f769e0d4e1d79fe783bfbb14d71dc1f24f1f8451"
integrity sha1-ITwA0r+3/+27CBOBpBhGjKRwthg= integrity sha1-92ng1OHXn+eDv7sU1x3B8k8fhFE=
dependencies: dependencies:
"@material/feature-targeting" "13.0.0-canary.5981207f7.0" "@material/feature-targeting" "13.0.0-canary.b47dd37a6.0"
"@material/theme" "13.0.0-canary.5981207f7.0" "@material/theme" "13.0.0-canary.b47dd37a6.0"
tslib "^2.1.0" tslib "^2.1.0"
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
@ -1165,6 +1165,11 @@
"@nodelib/fs.scandir" "2.1.5" "@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0" fastq "^1.6.0"
"@popperjs/core@^2.8.3":
version "2.9.3"
resolved "https://registry.nlark.com/@popperjs/core/download/@popperjs/core-2.9.3.tgz?cache=0&sync_timestamp=1628004480078&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40popperjs%2Fcore%2Fdownload%2F%40popperjs%2Fcore-2.9.3.tgz#8b68da1ebd7fc603999cf6ebee34a4899a14b88e"
integrity sha1-i2jaHr1/xgOZnPbr7jSkiZoUuI4=
"@rollup/pluginutils@^4.1.0": "@rollup/pluginutils@^4.1.0":
version "4.1.1" version "4.1.1"
resolved "https://registry.nlark.com/@rollup/pluginutils/download/@rollup/pluginutils-4.1.1.tgz?cache=0&sync_timestamp=1626395301062&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40rollup%2Fpluginutils%2Fdownload%2F%40rollup%2Fpluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec" resolved "https://registry.nlark.com/@rollup/pluginutils/download/@rollup/pluginutils-4.1.1.tgz?cache=0&sync_timestamp=1626395301062&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40rollup%2Fpluginutils%2Fdownload%2F%40rollup%2Fpluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec"
@ -2506,6 +2511,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
dependencies: dependencies:
safe-buffer "~5.1.1" safe-buffer "~5.1.1"
cooltipz-css@^1.6.8:
version "1.6.8"
resolved "https://registry.nlark.com/cooltipz-css/download/cooltipz-css-1.6.8.tgz#9913871abb78583faa4aabccec7c19d8bc5ecc95"
integrity sha1-mROHGrt4WD+qSqvM7HwZ2LxezJU=
core-js@^3.15.2: core-js@^3.15.2:
version "3.15.2" version "3.15.2"
resolved "https://registry.nlark.com/core-js/download/core-js-3.15.2.tgz?cache=0&sync_timestamp=1624966056491&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcore-js%2Fdownload%2Fcore-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61" resolved "https://registry.nlark.com/core-js/download/core-js-3.15.2.tgz?cache=0&sync_timestamp=1624966056491&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fcore-js%2Fdownload%2Fcore-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61"
@ -6473,6 +6483,13 @@ throat@^6.0.1:
resolved "https://registry.nlark.com/throat/download/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" resolved "https://registry.nlark.com/throat/download/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
integrity sha1-1RT+2tlXQMEsLX/HDqhj61Gt43U= integrity sha1-1RT+2tlXQMEsLX/HDqhj61Gt43U=
tippy.js@^6.3.1:
version "6.3.1"
resolved "https://registry.nlark.com/tippy.js/download/tippy.js-6.3.1.tgz#3788a007be7015eee0fd589a66b98fb3f8f10181"
integrity sha1-N4igB75wFe7g/ViaZrmPs/jxAYE=
dependencies:
"@popperjs/core" "^2.8.3"
tmpl@1.0.x: tmpl@1.0.x:
version "1.0.4" version "1.0.4"
resolved "https://registry.nlark.com/tmpl/download/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" resolved "https://registry.nlark.com/tmpl/download/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
@ -7022,6 +7039,13 @@ vue-router@^4.0.10:
dependencies: dependencies:
"@vue/devtools-api" "^6.0.0-beta.14" "@vue/devtools-api" "^6.0.0-beta.14"
vue-tippy@^6.0.0-alpha.31:
version "6.0.0-alpha.31"
resolved "https://registry.nlark.com/vue-tippy/download/vue-tippy-6.0.0-alpha.31.tgz#f5df1e0be50755e22f63b5edfad05e3067c3f554"
integrity sha1-9d8eC+UHVeIvY7Xt+tBeMGfD9VQ=
dependencies:
tippy.js "^6.3.1"
vue-tsc@^0.2.0: vue-tsc@^0.2.0:
version "0.2.2" version "0.2.2"
resolved "https://registry.nlark.com/vue-tsc/download/vue-tsc-0.2.2.tgz#e7fd5e5c789beb31840ad26082cfc8bb6356e733" resolved "https://registry.nlark.com/vue-tsc/download/vue-tsc-0.2.2.tgz#e7fd5e5c789beb31840ad26082cfc8bb6356e733"