Add semantic ui types

This commit is contained in:
wvffle 2022-07-20 18:15:40 +00:00 committed by Georg Krause
parent af0129b598
commit 405eed0c0f
19 changed files with 371 additions and 320 deletions

View File

@ -58,6 +58,7 @@
"@types/jquery": "3.5.14",
"@types/lodash-es": "4.17.6",
"@types/qs": "6.9.7",
"@types/semantic-ui": "^2.2.7",
"@types/showdown": "^2.0.0",
"@typescript-eslint/eslint-plugin": "5.30.5",
"@vitejs/plugin-vue": "2.3.3",

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import Modal from '~/components/semantic/Modal.vue'
import SemanticModal from '~/components/semantic/Modal.vue'
import { useVModel } from '@vueuse/core'
import { computed } from 'vue'
import { useGettext } from 'vue3-gettext'
@ -103,7 +103,7 @@ const player = computed(() => [
</script>
<template>
<modal v-model:show="showRef">
<semantic-modal v-model:show="showRef">
<header class="header">
<translate translate-context="*/*/*/Noun">
Keyboard shortcuts
@ -156,5 +156,5 @@ const player = computed(() => [
</translate>
</button>
</footer>
</modal>
</semantic-modal>
</template>

View File

@ -1,3 +1,133 @@
<script setup lang="ts">
import type { RouteRecordName } from 'vue-router'
import UserModal from '~/components/common/UserModal.vue'
import Logo from '~/components/Logo.vue'
import SearchBar from '~/components/audio/SearchBar.vue'
import UserMenu from '~/components/common/UserMenu.vue'
import SemanticModal from '~/components/semantic/Modal.vue'
import useThemeList from '~/composables/useThemeList'
import useTheme from '~/composables/useTheme'
import { useRoute } from 'vue-router'
import { computed, ref, watch, watchEffect, onMounted } from 'vue'
import { useGettext } from 'vue3-gettext'
import { useStore } from '~/store'
import { setupDropdown } from '~/utils/fomantic'
interface Props {
width: number
}
defineProps<Props>()
const store = useStore()
const theme = useTheme()
const themes = useThemeList()
const { $pgettext } = useGettext()
const route = useRoute()
const isCollapsed = ref(true)
watch(() => route.path, () => (isCollapsed.value = true))
const additionalNotifications = computed(() => store.getters['ui/additionalNotifications'])
const logoUrl = computed(() => store.state.auth.authenticated ? 'library.index' : 'index')
const labels = computed(() => ({
mainMenu: $pgettext('Sidebar/*/Hidden text', 'Main menu'),
selectTrack: $pgettext('Sidebar/Player/Hidden text', 'Play this track'),
pendingFollows: $pgettext('Sidebar/Notifications/Hidden text', 'Pending follow requests'),
pendingReviewEdits: $pgettext('Sidebar/Moderation/Hidden text', 'Pending review edits'),
pendingReviewReports: $pgettext('Sidebar/Moderation/Hidden text', 'Pending review reports'),
language: $pgettext('Sidebar/Settings/Dropdown.Label/Short, Verb', 'Language'),
theme: $pgettext('Sidebar/Settings/Dropdown.Label/Short, Verb', 'Theme'),
addContent: $pgettext('*/Library/*/Verb', 'Add content'),
administration: $pgettext('Sidebar/Admin/Title/Noun', 'Administration')
}))
type SidebarMenuTabs = 'explore' | 'myLibrary'
const expanded = ref<SidebarMenuTabs>('explore')
const ROUTE_MAPPINGS: Record<SidebarMenuTabs, RouteRecordName[]> = {
explore: [
'search',
'library.index',
'library.podcasts.browse',
'library.albums.browse',
'library.albums.detail',
'library.artists.browse',
'library.artists.detail',
'library.tracks.detail',
'library.playlists.browse',
'library.playlists.detail',
'library.radios.browse',
'library.radios.detail'
],
myLibrary: [
'library.me',
'library.albums.me',
'library.artists.me',
'library.playlists.me',
'library.radios.me',
'favorites'
]
}
watchEffect(() => {
if (ROUTE_MAPPINGS.explore.includes(route.name as RouteRecordName)) {
expanded.value = 'explore'
return
}
if (ROUTE_MAPPINGS.myLibrary.includes(route.name as RouteRecordName)) {
expanded.value = 'myLibrary'
return
}
expanded.value = store.state.auth.authenticated ? 'myLibrary' : 'explore'
})
const moderationNotifications = computed(() =>
store.state.ui.notifications.pendingReviewEdits
+ store.state.ui.notifications.pendingReviewReports
+ store.state.ui.notifications.pendingReviewRequests
)
const isProduction = import.meta.env.PROD
const showUserModal = ref(false)
const showLanguageModal = ref(false)
const showThemeModal = ref(false)
// TODO (wvffle): Use current language this.$language.current
const languageSelection = undefined
// export default {
// watch: {
// languageSelection: function (v) {
// this.$store.dispatch('ui/currentLanguage', v)
// this.$refs.languageModal.closeModal()
// }
// },
// }
watch(() => store.state.auth.authenticated, (authenticated) => {
if (authenticated) {
setupDropdown('.admin-dropdown')
}
setupDropdown('.user-dropdown')
}, { immediate: true })
watch(() => store.state.auth.availablePermissions, () => {
if (store.state.auth.authenticated) {
setupDropdown('.admin-dropdown')
}
}, { immediate: true })
onMounted(() => {
document.getElementById('fake-sidebar')?.classList.add('loaded')
})
</script>
<template>
<aside :class="['ui', 'vertical', 'left', 'visible', 'wide', {'collapsed': isCollapsed}, 'sidebar', 'component-sidebar']">
<header class="ui basic segment header-wrapper">
@ -54,7 +184,7 @@
:to="{name: 'manage.moderation.reports.list', query: {q: 'resolved:no'}}"
>
<div
v-if="$store.state.ui.notifications.pendingReviewReports + $store.state.ui.notifications.pendingReviewRequests> 0"
v-if="$store.state.ui.notifications.pendingReviewReports + $store.state.ui.notifications.pendingReviewRequests > 0"
:title="labels.pendingReviewReports"
:class="['ui', 'circular', 'mini', 'right floated', 'accent', 'label']"
>
@ -131,10 +261,10 @@
@click.prevent.exact="showUserModal = !showUserModal"
>
<img
v-if="$store.state.auth.authenticated && $store.state.auth.profile.avatar && $store.state.auth.profile.avatar.urls.medium_square_crop"
v-if="$store.state.auth.authenticated && $store.state.auth.profile?.avatar.urls.medium_square_crop"
class="ui avatar image"
alt=""
:src="$store.getters['instance/absoluteUrl']($store.state.auth.profile.avatar.urls.medium_square_crop)"
:src="$store.getters['instance/absoluteUrl']($store.state.auth.profile?.avatar.urls.medium_square_crop)"
>
<actor-avatar
v-else-if="$store.state.auth.authenticated"
@ -157,7 +287,7 @@
@show-theme-modal-event="showThemeModal=true"
@show-language-modal-event="showLanguageModal=true"
/>
<modal
<semantic-modal
ref="languageModal"
v-model:show="showLanguageModal"
:fullscreen="false"
@ -178,17 +308,17 @@
:key="key"
>
<input
:id="key"
:id="`${key}`"
v-model="languageSelection"
type="radio"
name="language"
:value="key"
>
<label :for="key">{{ language }}</label>
<label :for="`${key}`">{{ language }}</label>
</fieldset>
</div>
</modal>
<modal
</semantic-modal>
<semantic-modal
ref="themeModal"
v-model:show="showThemeModal"
:fullscreen="false"
@ -218,7 +348,7 @@
<label :for="t.key">{{ t.name }}</label>
</fieldset>
</div>
</modal>
</semantic-modal>
<div class="item collapse-button-wrapper">
<button
:class="['ui', 'basic', 'big', {'vibrant': !isCollapsed}, 'inverted icon', 'collapse', 'button']"
@ -269,27 +399,27 @@
</h1>
<div class="ui small hidden divider" />
<section
:class="['ui', 'bottom', 'attached', {active: selectedTab === 'library'}, 'tab']"
:aria-label="labels.mainMenu"
class="ui bottom attached active tab"
>
<nav
class="ui vertical large fluid inverted menu"
role="navigation"
:aria-label="labels.mainMenu"
>
<div :class="[{collapsed: !exploreExpanded}, 'collapsible item']">
<div :class="[{ collapsed: expanded !== 'explore' }, 'collapsible item']">
<h2
class="header"
role="button"
tabindex="0"
@click="exploreExpanded = true"
@focus="exploreExpanded = true"
@click="expanded = 'explore'"
@focus="expanded = 'explore'"
>
<translate translate-context="*/*/*/Verb">
Explore
</translate>
<i
v-if="!exploreExpanded"
v-if="expanded !== 'explore'"
class="angle right icon"
/>
</h2>
@ -355,20 +485,20 @@
</div>
<div
v-if="$store.state.auth.authenticated"
:class="[{collapsed: !myLibraryExpanded}, 'collapsible item']"
:class="[{ collapsed: expanded !== 'myLibrary' }, 'collapsible item']"
>
<h3
class="header"
role="button"
tabindex="0"
@click="myLibraryExpanded = true"
@focus="myLibraryExpanded = true"
@click="expanded = 'myLibrary'"
@focus="expanded = 'myLibrary'"
>
<translate translate-context="*/*/*/Noun">
My Library
</translate>
<i
v-if="!myLibraryExpanded"
v-if="expanded !== 'myLibrary'"
class="angle right icon"
/>
</h3>
@ -451,7 +581,7 @@
</div>
</div>
<div
v-if="!production"
v-if="!isProduction"
class="item"
>
<a
@ -467,251 +597,6 @@
</aside>
</template>
<script>
import { mapState, mapActions, mapGetters } from 'vuex'
import UserModal from '~/components/common/UserModal.vue'
import Logo from '~/components/Logo.vue'
import SearchBar from '~/components/audio/SearchBar.vue'
import UserMenu from '~/components/common/UserMenu.vue'
import Modal from '~/components/semantic/Modal.vue'
import $ from 'jquery'
import useThemeList from '~/composables/useThemeList'
import useTheme from '~/composables/useTheme'
import { useRoute } from 'vue-router'
import { computed } from 'vue'
export default {
name: 'Sidebar',
components: {
SearchBar,
Logo,
UserMenu,
UserModal,
Modal
},
props: {
width: { type: Number, required: true }
},
setup () {
const theme = useTheme()
const themes = useThemeList()
const route = useRoute()
const url = computed(() => route.path)
return {
theme,
themes,
url
}
},
data () {
return {
selectedTab: 'library',
isCollapsed: true,
fetchInterval: null,
exploreExpanded: false,
myLibraryExpanded: false,
showUserModal: false,
showLanguageModal: false,
showThemeModal: false,
languageSelection: this.$language.current
}
},
destroy () {
if (this.fetchInterval) {
clearInterval(this.fetchInterval)
}
},
computed: {
...mapState({
queue: state => state.queue
}),
...mapGetters({
additionalNotifications: 'ui/additionalNotifications'
}),
labels () {
const mainMenu = this.$pgettext('Sidebar/*/Hidden text', 'Main menu')
const selectTrack = this.$pgettext('Sidebar/Player/Hidden text', 'Play this track')
const pendingFollows = this.$pgettext('Sidebar/Notifications/Hidden text', 'Pending follow requests')
const pendingReviewEdits = this.$pgettext('Sidebar/Moderation/Hidden text', 'Pending review edits')
const language = this.$pgettext(
'Sidebar/Settings/Dropdown.Label/Short, Verb',
'Language')
const theme = this.$pgettext(
'Sidebar/Settings/Dropdown.Label/Short, Verb',
'Theme')
return {
pendingFollows,
mainMenu,
selectTrack,
pendingReviewEdits,
language,
theme,
addContent: this.$pgettext('*/Library/*/Verb', 'Add content'),
administration: this.$pgettext('Sidebar/Admin/Title/Noun', 'Administration')
}
},
logoUrl () {
if (this.$store.state.auth.authenticated) {
return 'library.index'
} else {
return 'index'
}
},
focusedMenu () {
const mapping = {
search: 'exploreExpanded',
'library.index': 'exploreExpanded',
'library.podcasts.browse': 'exploreExpanded',
'library.albums.browse': 'exploreExpanded',
'library.albums.detail': 'exploreExpanded',
'library.artists.browse': 'exploreExpanded',
'library.artists.detail': 'exploreExpanded',
'library.tracks.detail': 'exploreExpanded',
'library.playlists.browse': 'exploreExpanded',
'library.playlists.detail': 'exploreExpanded',
'library.radios.browse': 'exploreExpanded',
'library.radios.detail': 'exploreExpanded',
'library.me': 'myLibraryExpanded',
'library.albums.me': 'myLibraryExpanded',
'library.artists.me': 'myLibraryExpanded',
'library.playlists.me': 'myLibraryExpanded',
'library.radios.me': 'myLibraryExpanded',
favorites: 'myLibraryExpanded'
}
const m = mapping[this.$route.name]
if (m) {
return m
}
if (this.$store.state.auth.authenticated) {
return 'myLibraryExpanded'
} else {
return 'exploreExpanded'
}
},
moderationNotifications () {
return (
this.$store.state.ui.notifications.pendingReviewEdits +
this.$store.state.ui.notifications.pendingReviewReports +
this.$store.state.ui.notifications.pendingReviewRequests
)
},
production () {
return import.meta.env.PROD
}
},
watch: {
url: function () {
this.isCollapsed = true
},
'$store.state.moderation.lastUpdate': function () {
this.applyContentFilters()
},
'$store.state.auth.authenticated': {
immediate: true,
handler (v) {
if (v) {
this.$nextTick(() => {
this.setupDropdown('.user-dropdown')
this.setupDropdown('.admin-dropdown')
})
} else {
this.$nextTick(() => {
this.setupDropdown('.user-dropdown')
})
}
}
},
'$store.state.auth.availablePermissions': {
immediate: true,
handler (v) {
this.$nextTick(() => {
this.setupDropdown('.admin-dropdown')
})
},
deep: true
},
focusedMenu: {
immediate: true,
handler (n) {
if (n) {
this[n] = true
}
}
},
myLibraryExpanded (v) {
if (v) {
this.exploreExpanded = false
}
},
exploreExpanded (v) {
if (v) {
this.myLibraryExpanded = false
}
},
languageSelection: function (v) {
this.$store.dispatch('ui/currentLanguage', v)
this.$refs.languageModal.closeModal()
}
},
mounted () {
this.$nextTick(() => {
document.getElementById('fake-sidebar').classList.add('loaded')
})
},
methods: {
...mapActions({
cleanTrack: 'queue/cleanTrack'
}),
applyContentFilters () {
const artistIds = this.$store.getters['moderation/artistFilters']().map((f) => {
return f.target.id
})
if (artistIds.length === 0) {
return
}
const self = this
const tracks = this.tracks.slice().reverse()
tracks.forEach(async (t, i) => {
// we loop from the end because removing index from the start can lead to removing the wrong tracks
const realIndex = tracks.length - i - 1
const matchArtist = artistIds.indexOf(t.artist.id) > -1
if (matchArtist) {
return await self.cleanTrack(realIndex)
}
if (t.album && artistIds.indexOf(t.album.artist.id) > -1) {
return await self.cleanTrack(realIndex)
}
})
},
setupDropdown (selector) {
const self = this
$(self.$el).find(selector).dropdown({
selectOnKeydown: false,
action: function (text, value, $el) {
// used ton ensure focusing the dropdown and clicking via keyboard
// works as expected
const link = $($el).closest('a')
const url = link.attr('href')
if (url) {
if (url.startsWith('http')) {
window.open(url, '_blank').focus()
} else {
self.$router.push(url)
}
}
$(self.$el).find(selector).dropdown('hide')
}
})
}
}
}
</script>
<style>
[type="radio"] {
position: absolute;

View File

@ -7,7 +7,7 @@ import { useGettext } from 'vue3-gettext'
import usePlayOptions from '~/composables/audio/usePlayOptions'
import useReport from '~/composables/moderation/useReport'
import { useCurrentElement } from '@vueuse/core'
import jQuery from 'jquery'
import { setupDropdown, getDropdown } from '~/utils/fomantic'
interface Props extends PlayOptionsProps {
dropdownIconClasses?: string[]
@ -95,27 +95,13 @@ const title = computed(() => {
}
})
const el = useCurrentElement()
watch(clicked, async () => {
await nextTick()
// @ts-expect-error dropdown is from semantic ui
jQuery(el.value).find('.ui.dropdown').dropdown({
selectOnKeydown: false,
action (text: unknown, value: unknown, $el: JQuery) {
// used to ensure focusing the dropdown and clicking via keyboard
// works as expected
$el[0].click()
await setupDropdown()
// @ts-expect-error dropdown is from semantic ui
jQuery(el.value).find('.ui.dropdown').dropdown('hide')
}
})
// @ts-expect-error dropdown is from semantic ui
jQuery(el.value).find('.ui.dropdown').dropdown('show', function () {
getDropdown().dropdown('show', function () {
// little magic to ensure the menu is always visible in the viewport
// By default, try to diplay it on the right if there is enough room
const menu = jQuery(el.value).find('.ui.dropdown').find('.menu')
const menu = getDropdown().find('.menu')
const viewportOffset = menu.get(0)?.getBoundingClientRect() ?? { right: 0, left: 0 }
const viewportWidth = document.documentElement.clientWidth
const rightOverflow = viewportOffset.right - viewportWidth

View File

@ -24,7 +24,6 @@ onMounted(() => {
...props.message
}
// @ts-expect-error toast is from semantic ui
$('body').toast(params)
$('.ui.toast.visible').last().attr('role', 'alert')
})

View File

@ -100,7 +100,6 @@ const fetchFavorites = async () => {
onBeforeRouteUpdate(fetchFavorites)
fetchFavorites()
// @ts-expect-error semantic ui
onMounted(() => $('.ui.dropdown').dropdown())
const { $pgettext } = useGettext()

View File

@ -104,7 +104,6 @@ watch(() => store.state.moderation.lastUpdate, fetchData)
onBeforeRouteUpdate(fetchData)
fetchData()
// @ts-expect-error semantic ui
onMounted(() => $('.ui.dropdown').dropdown())
const { $pgettext } = useGettext()

View File

@ -108,7 +108,6 @@ watch([() => store.state.moderation.lastUpdate, excludeCompilation], fetchData)
onBeforeRouteUpdate(fetchData)
fetchData()
// @ts-expect-error semantic ui
onMounted(() => $('.ui.dropdown').dropdown())
const { $pgettext } = useGettext()

View File

@ -28,7 +28,7 @@ const headers = computed(() => {
const patchFileData = (file: VueUploadItem, data: Record<string, unknown> = {}) => {
let metadata = data.import_metadata as Record<string, unknown>
// @ts-expect-error Taken from vue-upload-component@3.1.2
// @ts-expect-error Taken from 3.1.2
const filename: string = file.file.name || file.file.filename || file.name
data.source = `upload://${filename}`

View File

@ -110,7 +110,6 @@ watch(() => store.state.moderation.lastUpdate, fetchData)
onBeforeRouteUpdate(fetchData)
fetchData()
// @ts-expect-error semantic ui
onMounted(() => $('.ui.dropdown').dropdown())
const { $pgettext } = useGettext()

View File

@ -93,7 +93,6 @@ const hasFavorites = computed(() => store.state.favorites.count > 0)
onBeforeRouteUpdate(fetchData)
fetchData()
// @ts-expect-error semantic ui
onMounted(() => $('.ui.dropdown').dropdown())
const { $pgettext } = useGettext()

View File

@ -58,7 +58,6 @@ const privacyLevelChoices = computed(() => [
const el = useCurrentElement()
onMounted(async () => {
await nextTick()
// @ts-expect-error dropdown is from semantic ui
$(el.value).find('.dropdown').dropdown()
})

View File

@ -25,9 +25,8 @@ const { activate, deactivate, pause, unpause } = useFocusTrap(modal)
const show = useVModel(props, 'show', emit)
const control = ref()
const control = ref<JQuery | undefined>()
const initModal = () => {
// @ts-expect-error modal is from semantic ui
control.value = $(modal.value).modal({
duration: 100,
onApprove: () => emit('approved'),

View File

@ -133,7 +133,6 @@ export default (props: PlayOptionsProps) => {
const el = useCurrentElement()
const enqueue = async () => {
// @ts-expect-error dropdown is from semantic ui
jQuery(el.value).find('.ui.dropdown').dropdown('hide')
const tracks = await getPlayableTracks()
@ -141,7 +140,6 @@ export default (props: PlayOptionsProps) => {
}
const enqueueNext = async (next = false) => {
// @ts-expect-error dropdown is from semantic ui
jQuery(el.value).find('.ui.dropdown').dropdown('hide')
const tracks = await getPlayableTracks()
@ -160,7 +158,6 @@ export default (props: PlayOptionsProps) => {
const replacePlay = async () => {
store.dispatch('queue/clean')
// @ts-expect-error dropdown is from semantic ui
jQuery(el.value).find('.ui.dropdown').dropdown('hide')
const tracks = await getPlayableTracks()

View File

@ -1,24 +1,11 @@
import type { InitModule } from '~/types'
import jQuery from '~/jquery'
import { setupDropdown } from '~/utils/fomantic'
export const install: InitModule = ({ app, store }) => {
app.directive('title', function (el, binding) {
store.commit('ui/pageTitle', binding.value)
})
app.directive('dropdown', function (el, binding) {
// @ts-expect-error dropdown is from semantic ui
jQuery(el).dropdown({
selectOnKeydown: false,
action (text: string, value: string, $el: JQuery<HTMLElement>) {
// used to ensure focusing the dropdown and clicking via keyboard
// works as expected
$el[0]?.click()
// @ts-expect-error dropdown is from semantic ui
jQuery(el).find('.ui.dropdown').dropdown('hide')
},
...(binding.value || {})
})
})
app.directive('dropdown', setupDropdown)
}

View File

@ -0,0 +1,34 @@
/// <reference types="semantic-ui" />
import $ from 'jquery'
import { nextTick } from 'vue'
import { useCurrentElement } from '@vueuse/core'
const el = useCurrentElement()
export const getDropdown = (selector = '.ui.dropdown'): JQuery => {
return $(el.value).find(selector)
}
export const setupDropdown = async (selector: string | HTMLElement = '.ui.dropdown') => {
if (typeof selector === 'string') {
await nextTick()
}
const $dropdown = typeof selector === 'string'
? $(el.value).find(selector)
: $(selector)
$dropdown.dropdown({
selectOnKeydown: false,
action (text: unknown, value: unknown, $el: JQuery) {
// used to ensure focusing the dropdown and clicking via keyboard
// works as expected
$el[0]?.click()
$dropdown.dropdown('hide')
}
})
return $dropdown
}

View File

@ -132,15 +132,14 @@ if (route.hash) {
scrollTo(route.hash.slice(1))
}
onMounted(() => {
// @ts-expect-error dropdown is from semantic ui
$('select.dropdown').dropdown()
const el = useCurrentElement()
onMounted(async () => {
await nextTick()
$(el.value).find('select.dropdown').dropdown()
})
const el = useCurrentElement()
watch(settingsData, async () => {
await nextTick()
// @ts-expect-error sticky is from semantic ui
$(el.value).find('.sticky').sticky({ context: '#settings-grid' })
})

View File

@ -89,7 +89,6 @@ const fetchData = async () => {
onBeforeRouteUpdate(fetchData)
fetchData()
// @ts-expect-error semantic ui
onMounted(() => $('.ui.dropdown').dropdown())
const { $pgettext } = useGettext()

View File

@ -1422,7 +1422,7 @@
jest-matcher-utils "^28.0.0"
pretty-format "^28.0.0"
"@types/jquery@3.5.14":
"@types/jquery@*", "@types/jquery@3.5.14":
version "3.5.14"
resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.14.tgz#ac8e11ee591e94d4d58da602cb3a5a8320dee577"
integrity sha512-X1gtMRMbziVQkErhTQmSe2jFwwENA/Zr+PprCkF63vFq+Yt5PZ4AlKqgmeNlwgn7dhsXEK888eIW2520EpC+xg==
@ -1488,6 +1488,177 @@
dependencies:
"@types/node" "*"
"@types/semantic-ui-accordion@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-accordion/-/semantic-ui-accordion-2.2.2.tgz#2f3b9d60a981d9eddc3705619079defaacc3aee0"
integrity sha512-XClXI/20W7iFLQ7eyslZswbdv3A4qWEnFz8JvOylGatCW7biTLVhMBPcN0b17TZ1GeV4V/l3ctmvTEBCHvg8CA==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-api@*":
version "2.2.4"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-api/-/semantic-ui-api-2.2.4.tgz#ea9cad381b38b77f95fa3bf679d7c5273c7b20dd"
integrity sha512-6IvCjZDJ0TVb1EtnNFQPNyVmOZnLGPEKyEAs9G0FF3XuAyyOdtfD4NGHJ0kknnX1FD+++ye0EuSVFDutbwEFWw==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-checkbox@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-checkbox/-/semantic-ui-checkbox-2.2.2.tgz#bb19b20d503103a724c9dc79f71132edb092a362"
integrity sha512-ZTAy3yNwOAaoznxsFoR33XopJnyyzAGrLeDpn7hVTkUYm7wgGsgOpRfG2psdM3fIOCkZkkE9IEAp1pLGBifL1g==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-dimmer@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-dimmer/-/semantic-ui-dimmer-2.2.2.tgz#667185161c31d046a51a6d71097d2909829e1423"
integrity sha512-wK7da/70UJ9AU7Ju2MeOO9sjRPrhU6jf+VvHiTwlaCGm7+ALiJThd88D1iB6ODDQpm+ebjIbQkvAmDSkMpmKlg==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-dropdown@*":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-dropdown/-/semantic-ui-dropdown-2.2.3.tgz#fffafea2a26dcb85fefc74a23d6a764f21a75b61"
integrity sha512-y2ZIiEWvFFyLu7+yqNV550U9hs3sfqP7ajLxHEWlGjxGS4NsJmy9In7/UcxnpJB+JkanC4JkyogEN6wRlbqvhw==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-api" "*"
"@types/semantic-ui-embed@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-embed/-/semantic-ui-embed-2.2.2.tgz#5b851bc966c06812550410348da7f8ea866e0c02"
integrity sha512-5sW99BtK2SIBs9/sSM/0vMr6tphPyPXHyClhFX1tJi0L5ZH0wEmf6XcBRZgROe3ueHYVaJ0Pt/zwPQ5SMW0xDg==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-form@*":
version "2.2.6"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-form/-/semantic-ui-form-2.2.6.tgz#767c364c92fb3977f221b8c72e094e0928d4a024"
integrity sha512-khj3o6w2TWN9Bh7yZhsosUfAPMBRP/rD3DiApZrPUaioCHf0VrDtYuiqJXTd/Qt7cZW2w+NgZ1riV/3leXx8iA==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-modal@*":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-modal/-/semantic-ui-modal-2.2.3.tgz#482e8ca3323b22e7247ff92249a52a8bc2fccc6d"
integrity sha512-Th48BFk1pd4kluFjCUDKn7Aml3xoLdFFK8wFQRz6UsOMdvsXx2OrNkubhjqc79tcBzONC7NszSW2ImslPPHNCg==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-dimmer" "*"
"@types/semantic-ui-nag@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-nag/-/semantic-ui-nag-2.2.2.tgz#93e9cc410aa17b273ef73a705666815a7c2a09a6"
integrity sha512-gqjSFmMLw8vtPa6/Rv/mFBK1mdqaUbLkhUA4CsTDhkibUqnNqpvI/d1XFFLdC/ULu9v7UloMTCndSGKao+q5oA==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-popup@*":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-popup/-/semantic-ui-popup-2.2.3.tgz#cdf391d0e16ffbfdc34c7fee85e85d20a9323c5a"
integrity sha512-tw7FXUTAs+GEU939RBpOCVq9H8vYpsr8uYvJC0RUxXCYXCUHsgYzgIIklKoD+xPvUCf34MHnMBwrrTCMJosxGg==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-progress@*":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-progress/-/semantic-ui-progress-2.2.3.tgz#2ad3e2b69c5c5927aa4c11634cdf0a04ab53b36f"
integrity sha512-gv0i4+/uVbUJnuTzNv2oEqJ8CMQPeAR6K+s2zm1r4waH+8ZQ0SKM1DZ4t3w4gEMxhXqZVlLlyIhfY1SmUI0GuQ==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-rating@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-rating/-/semantic-ui-rating-2.2.2.tgz#d35807b61ebc6b4f2a977b430fbd862fa5f5b5a7"
integrity sha512-9497T8bEnkadWtQDl5Hno9lviZ2bJjx5rKd/Gfq6PWZ1/4/71LrYdH1DSr+sHYJ5HkaSA0b7GFVCTxi9pEdd6Q==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-search@*":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-search/-/semantic-ui-search-2.2.3.tgz#7da1a62ed116a1aa0baee2a9c66196b16f643e13"
integrity sha512-JVrrW9uakXTudNm1MGrkRpirL2vm8NCVtrPyH6zIbBNqi08UPeHY8yxjnFpTPv5sMKBGGhkSn9cYrGz6Cweg2Q==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-api" "*"
"@types/semantic-ui-shape@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-shape/-/semantic-ui-shape-2.2.2.tgz#ce3bd95e4ec1127380343910c4766a4f070c1336"
integrity sha512-bXaeheuuDY3rAmA5QQRAA0fzMiEkhRgZts5i7w/d1XlMHCVNeHIIAbhTurl3bPwTlbr0NI7T3ZmxH0EKRVdIEg==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-sidebar@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-sidebar/-/semantic-ui-sidebar-2.2.2.tgz#792464d6e381354c8c1e935635c9010b1366f4a9"
integrity sha512-fm/whmNiyTzQwduc4maV9XjdwVc4pVlkhX5vippW9ukCCkVGY8qBgQKHFYhAHPhe7sCsGIuS+Vpr83t8X7Fg8w==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-site@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-site/-/semantic-ui-site-2.2.2.tgz#25a358ca572aa0e811f2f912ab6872ef897c8bbe"
integrity sha512-XxwUxqpBLAlPpO7OqAYIdBRsZTmKLXvSzBLczms3JshnoChEZbxtKRYxSxgK93Y4XYCfKnpXQXEF6RIw5FF/mA==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-sticky@*":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-sticky/-/semantic-ui-sticky-2.2.3.tgz#1317d2eac9b42d8088f8f0f3228684efa0ce6a84"
integrity sha512-HOhd+W75u9Hk0owQXUGdDKpvVhKl/207hueZqTTREZPTmxALAHbl6bHKxnvcJqRerhOFdObQcCFZGL5DEXRtcA==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-tab@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-tab/-/semantic-ui-tab-2.2.2.tgz#4bae0c8ac1e970cd93fc31cf99f546e29ac9a069"
integrity sha512-o7a2TJAxjh7pVqRzpQmJd7hTcaDv/tAYJh2Aez5mYiRrFylhzwIrJAcXhSwVRVInPZkc8MDlBPg8Xm+QJ98rLw==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-api" "*"
"@types/semantic-ui-transition@*":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-transition/-/semantic-ui-transition-2.2.2.tgz#e03d9eec32c962a5c862112f75a53879c3628406"
integrity sha512-wZJICf3qCr+68zPvzTKC9nQJ3mneW+K/K9Y2KphxujWgMCkOQEetDNb5Dbt9YZe92L0SnaPaDgp1KVaKAortdw==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-visibility@*":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@types/semantic-ui-visibility/-/semantic-ui-visibility-2.2.3.tgz#254a126b502159e194fcbc9b8561e14c4ba215a1"
integrity sha512-4vfXjZHJhif8Rw4WQ691Zx2Y0vqdNF2D0AYT7ltQH1/mL/fCqEwTLndl3qvgCbxpniGbTnYRajqx1dk8+Ji/HQ==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui@^2.2.7":
version "2.2.7"
resolved "https://registry.yarnpkg.com/@types/semantic-ui/-/semantic-ui-2.2.7.tgz#4ae4242004aac11a21133d4f338e868b92605270"
integrity sha512-Uj6rby2GnuVyO7pj8vgUFsv5eaxb0ktpfasYcB/vXnSAeJ4cRjIOvxka+EoPjw3tPCY4/WlxRss8hsh7kRWzQg==
dependencies:
"@types/jquery" "*"
"@types/semantic-ui-accordion" "*"
"@types/semantic-ui-api" "*"
"@types/semantic-ui-checkbox" "*"
"@types/semantic-ui-dimmer" "*"
"@types/semantic-ui-dropdown" "*"
"@types/semantic-ui-embed" "*"
"@types/semantic-ui-form" "*"
"@types/semantic-ui-modal" "*"
"@types/semantic-ui-nag" "*"
"@types/semantic-ui-popup" "*"
"@types/semantic-ui-progress" "*"
"@types/semantic-ui-rating" "*"
"@types/semantic-ui-search" "*"
"@types/semantic-ui-shape" "*"
"@types/semantic-ui-sidebar" "*"
"@types/semantic-ui-site" "*"
"@types/semantic-ui-sticky" "*"
"@types/semantic-ui-tab" "*"
"@types/semantic-ui-transition" "*"
"@types/semantic-ui-visibility" "*"
"@types/showdown@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/showdown/-/showdown-2.0.0.tgz#3e800eca8573848cac4e5555f4377ba3a0e7b1f2"