refactor(ui): move Chips component to composition API + TS (#3288)
* refactor(ui): move Chips component to composition API + TS * refactor(ui): move Chips component to composition API + TS
This commit is contained in:
parent
a02eb5445b
commit
1358336a76
@ -1,5 +1,4 @@
|
||||
<template>
|
||||
<Chips v-if="false" v-model="viewMode" :items="['open', 'archived']" />
|
||||
<ReportInfo
|
||||
v-for="report in reports.filter(
|
||||
(x) =>
|
||||
@ -17,7 +16,6 @@
|
||||
<p v-if="reports.length === 0">You don't have any active reports.</p>
|
||||
</template>
|
||||
<script setup>
|
||||
import Chips from "~/components/ui/Chips.vue";
|
||||
import ReportInfo from "~/components/ui/report/ReportInfo.vue";
|
||||
import { addReportMessage } from "~/helpers/threads.js";
|
||||
|
||||
|
||||
@ -640,7 +640,6 @@ import Badge from "~/components/ui/Badge.vue";
|
||||
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
|
||||
import CopyCode from "~/components/ui/CopyCode.vue";
|
||||
import Categories from "~/components/ui/search/Categories.vue";
|
||||
import Chips from "~/components/ui/Chips.vue";
|
||||
import Checkbox from "~/components/ui/Checkbox.vue";
|
||||
import FileInput from "~/components/ui/FileInput.vue";
|
||||
|
||||
@ -663,6 +662,7 @@ import Modal from "~/components/ui/Modal.vue";
|
||||
import ChevronRightIcon from "~/assets/images/utils/chevron-right.svg?component";
|
||||
|
||||
import AdPlaceholder from "~/components/ui/AdPlaceholder.vue";
|
||||
|
||||
export default defineNuxtComponent({
|
||||
components: {
|
||||
MarkdownEditor,
|
||||
@ -670,7 +670,6 @@ export default defineNuxtComponent({
|
||||
FileInput,
|
||||
Checkbox,
|
||||
ChevronRightIcon,
|
||||
Chips,
|
||||
Categories,
|
||||
DownloadIcon,
|
||||
EditIcon,
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Button } from "@modrinth/ui";
|
||||
import { Button, Chips } from "@modrinth/ui";
|
||||
import { HistoryIcon } from "@modrinth/assets";
|
||||
import {
|
||||
fetchExtraNotificationData,
|
||||
@ -58,7 +58,6 @@ import {
|
||||
markAsRead,
|
||||
} from "~/helpers/notifications.js";
|
||||
import NotificationItem from "~/components/ui/NotificationItem.vue";
|
||||
import Chips from "~/components/ui/Chips.vue";
|
||||
import CheckCheckIcon from "~/assets/images/utils/check-check.svg?component";
|
||||
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
|
||||
import Pagination from "~/components/ui/Pagination.vue";
|
||||
|
||||
@ -101,7 +101,7 @@
|
||||
</section>
|
||||
</template>
|
||||
<script setup>
|
||||
import Chips from "~/components/ui/Chips.vue";
|
||||
import { Chips } from "@modrinth/ui";
|
||||
import Avatar from "~/components/ui/Avatar.vue";
|
||||
import UnknownIcon from "~/assets/images/utils/unknown.svg?component";
|
||||
import EyeIcon from "~/assets/images/utils/eye.svg?component";
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="chips">
|
||||
<Button
|
||||
v-for="item in items"
|
||||
:key="item"
|
||||
:key="formatLabel(item)"
|
||||
class="btn"
|
||||
:class="{ selected: selected === item, capitalize: capitalize }"
|
||||
@click="toggleItem(item)"
|
||||
@ -12,62 +12,39 @@
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
|
||||
<script setup lang="ts" generic="T">
|
||||
import { CheckIcon } from '@modrinth/assets'
|
||||
</script>
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import Button from './Button.vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
modelValue: {
|
||||
required: true,
|
||||
type: String,
|
||||
},
|
||||
items: {
|
||||
required: true,
|
||||
type: Array,
|
||||
},
|
||||
neverEmpty: {
|
||||
default: true,
|
||||
type: Boolean,
|
||||
},
|
||||
formatLabel: {
|
||||
default: (x) => x,
|
||||
type: Function,
|
||||
},
|
||||
capitalize: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
items: T[]
|
||||
formatLabel?: (item: T) => string
|
||||
neverEmpty?: boolean
|
||||
capitalize?: boolean
|
||||
}>(),
|
||||
{
|
||||
neverEmpty: true,
|
||||
// Intentional any type, as this default should only be used for primitives (string or number)
|
||||
formatLabel: (item) => item.toString(),
|
||||
capitalize: true,
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
computed: {
|
||||
selected: {
|
||||
get() {
|
||||
return this.modelValue
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:modelValue', value)
|
||||
},
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.items.length > 0 && this.neverEmpty && !this.modelValue) {
|
||||
this.selected = this.items[0]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleItem(item) {
|
||||
if (this.selected === item && !this.neverEmpty) {
|
||||
this.selected = null
|
||||
} else {
|
||||
this.selected = item
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
const selected = defineModel<T | null>()
|
||||
|
||||
// If one always has to be selected, default to the first one
|
||||
if (props.items.length > 0 && props.neverEmpty && !selected.value) {
|
||||
selected.value = props.items[0]
|
||||
}
|
||||
|
||||
function toggleItem(item: T) {
|
||||
if (selected.value === item && !props.neverEmpty) {
|
||||
selected.value = null
|
||||
} else {
|
||||
selected.value = item
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user