fix: remove external dependency for icones (#805)

* change all icons to use iconify

* fix minor UI elements

* fix layout of table
This commit is contained in:
Hayden 2024-02-29 19:20:18 -06:00 committed by GitHub
parent cf166ac641
commit f91b33db38
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
40 changed files with 303 additions and 183 deletions

View file

@ -1,4 +1,6 @@
<script lang="ts" setup>
import MdiPlus from "~icons/mdi/mdi-plus";
const ctx = useAuthContext();
const api = useUserApi();
@ -103,7 +105,7 @@
<div class="dropdown">
<label tabindex="0" class="btn btn-primary btn-sm">
<span>
<Icon name="mdi-plus" class="mr-1 -ml-1" />
<MdiPlus class="mr-1 -ml-1" />
</span>
Create
</label>

View file

@ -32,7 +32,7 @@
<input ref="importRef" type="file" class="hidden" accept=".csv,.tsv" @change="setFile" />
<BaseButton type="button" @click="uploadCsv">
<Icon class="h-5 w-5 mr-2" name="mdi-upload" />
<MdiUpload class="h-5 w-5 mr-2" />
Upload
</BaseButton>
<p class="text-center pt-4 -mb-5">
@ -48,6 +48,7 @@
</template>
<script setup lang="ts">
import MdiUpload from "~icons/mdi/upload";
type Props = {
modelValue: boolean;
};

View file

@ -14,14 +14,14 @@
>
<div class="flex gap-1">
<template v-if="notify.type == 'success'">
<Icon name="heroicons-check" class="h-5 w-5" />
<MdiCheckboxMarkedCircle class="h-5 w-5" />
</template>
<template v-if="notify.type == 'info'">
<Icon name="heroicons-information-circle" class="h-5 w-5" />
<MdiInformationSlabCircle class="h-5 w-5" />
</template>
<template v-if="notify.type == 'error'">
<Icon name="heroicons-bell-alert" class="h-5 w-5" />
<MdiAlert class="h-5 w-5" />
</template>
{{ notify.message }}
</div>
@ -31,6 +31,10 @@
</template>
<script setup lang="ts">
import MdiCheckboxMarkedCircle from "~icons/mdi/checkbox-marked-circle";
import MdiInformationSlabCircle from "~icons/mdi/information-slab-circle";
import MdiAlert from "~icons/mdi/alert";
import { useNotifications } from "@/composables/use-notifier";
const { notifications, dropNotification } = useNotifications();

View file

@ -1,14 +0,0 @@
<template>
<div class="divider">
<div class="btn-group min-w-[180px] flex-nowrap">
<button name="options" class="btn btn-sm btn-primary" @click="$emit('edit')">
<Icon name="heroicons-pencil" class="h-5 w-5 mr-1" aria-hidden="true" />
<span> Edit </span>
</button>
<button name="options" class="btn btn-sm btn-primary" @click="$emit('delete')">
<Icon name="heroicons-trash" class="h-5 w-5 mr-1" aria-hidden="true" />
<span> Delete </span>
</button>
</div>
</div>
</template>

View file

@ -6,8 +6,8 @@
<slot name="title"></slot>
<template v-if="collapsable">
<span class="ml-2 swap swap-rotate" :class="`${collapsed ? 'swap-active' : ''}`">
<Icon class="h-6 w-6 swap-on" name="mdi-chevron-right" />
<Icon class="h-6 w-6 swap-off" name="mdi-chevron-down" />
<MdiChevronRight class="h-6 w-6 swap-on" />
<MdiChevronDown class="h-6 w-6 swap-off" />
</span>
</template>
</h3>
@ -34,6 +34,9 @@
</template>
<script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiChevronRight from "~icons/mdi/chevron-right";
defineProps<{
collapsable?: boolean;
}>();

View file

@ -1,7 +1,7 @@
<template>
<div class="pb-3">
<h3
class="text-3xl font-bold tracking-tight"
class="text-3xl font-bold tracking-tight flex items-center"
:class="{
'text-neutral-content': dark,
'text-content': !dark,

View file

@ -16,10 +16,10 @@
class="absolute inset-y-0 right-6 flex items-center rounded-r-md px-2 focus:outline-none"
@click="clear"
>
<Icon name="mdi-close" class="w-5 h-5" />
<MdiClose class="w-5 h-5" />
</button>
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
<Icon name="mdi-chevron-down" class="w-5 h-5" />
<MdiChevronDown class="w-5 h-5" />
</ComboboxButton>
<ComboboxOptions
v-if="computedItems.length > 0"
@ -49,7 +49,7 @@
active ? 'text-primary-content' : 'bg-primary',
]"
>
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" />
<MdiCheck class="h-5 w-5" aria-hidden="true" />
</span>
</slot>
</li>
@ -70,6 +70,9 @@
ComboboxButton,
ComboboxLabel,
} from "@headlessui/vue";
import MdiClose from "~icons/mdi/close";
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiCheck from "~icons/mdi/check";
type SupportValues = string | { [key: string]: any };

View file

@ -7,12 +7,14 @@
data-tip="Toggle Password Show"
@click="toggle()"
>
<Icon name="mdi-eye" class="h-5 w-5" />
<MdiEye name="mdi-eye" class="h-5 w-5" />
</button>
</div>
</template>
<script setup lang="ts">
import MdiEye from "~icons/mdi/eye";
type Props = {
modelValue: string;
placeholder?: string;

View file

@ -1,31 +0,0 @@
<script setup lang="ts">
import type { Ref } from "vue";
import type { IconifyIcon } from "@iconify/vue";
import { Icon as Iconify, loadIcon } from "@iconify/vue";
const nuxtApp = useNuxtApp();
const props = defineProps({
name: {
type: String,
required: true,
},
});
const icon: Ref<IconifyIcon | null> = ref(null);
const component = computed(() => nuxtApp.vueApp.component(props.name));
icon.value = await loadIcon(props.name).catch(() => null);
watch(
() => props.name,
async () => {
icon.value = await loadIcon(props.name).catch(() => null);
}
);
</script>
<template>
<Iconify v-if="icon" :icon="icon" class="inline-block" />
<Component :is="component" v-else-if="component" />
<span v-else>{{ name }}</span>
</template>

View file

@ -6,15 +6,15 @@
class="flex items-center justify-between py-3 pl-3 pr-4 text-sm"
>
<div class="flex w-0 flex-1 items-center">
<Icon name="mdi-paperclip" class="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
<MdiPaperclip class="h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
<span class="ml-2 w-0 flex-1 truncate"> {{ attachment.document.title }}</span>
</div>
<div class="ml-4 flex-shrink-0">
<a class="tooltip mr-2" data-tip="Download" :href="attachmentURL(attachment.id)" target="_blank">
<Icon class="h-5 w-5" name="mdi-download" />
<MdiDownload class="h-5 w-5" />
</a>
<a class="tooltip" data-tip="Open" :href="attachmentURL(attachment.id)" target="_blank">
<Icon class="h-5 w-5" name="mdi-open-in-new" />
<MdiOpenInNew class="h-5 w-5" />
</a>
</div>
</li>
@ -23,6 +23,9 @@
<script setup lang="ts">
import { ItemAttachment } from "~~/lib/api/types/data-contracts";
import MdiPaperclip from "~icons/mdi/paperclip";
import MdiDownload from "~icons/mdi/download";
import MdiOpenInNew from "~icons/mdi/open-in-new";
const props = defineProps({
attachments: {

View file

@ -17,7 +17,7 @@
<div class="divider my-0"></div>
<div class="flex justify-between gap-2">
<div v-if="item.insured" class="tooltip z-10" data-tip="Insured">
<Icon class="h-5 w-5 text-primary" name="mdi-shield-check" />
<MdiShieldCheck class="h-5 w-5 text-primary" />
</div>
<div class="tooltip" data-tip="Quantity">
<span class="badge h-5 w-5 badge-primary badge-sm text-xs">
@ -35,6 +35,7 @@
<script setup lang="ts">
import { ItemOut, ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiShieldCheck from "~icons/mdi/shield-check";
const api = useUserApi();

View file

@ -10,14 +10,14 @@
<div class="flex justify-center">
<BaseButton class="rounded-r-none" :loading="loading" type="submit">
<template #icon>
<Icon name="mdi-package-variant" class="swap-off h-5 w-5" />
<Icon name="mdi-package-variant-closed" class="swap-on h-5 w-5" />
<MdiPackageVariant class="swap-off h-5 w-5" />
<MdiPackageVariantClosed class="swap-on h-5 w-5" />
</template>
Create
</BaseButton>
<div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" />
<MdiChevronDown class="h-5 w-5" name="mdi-chevron-down" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li>
@ -38,6 +38,9 @@
import { ItemCreate, LabelOut, LocationOut } from "~~/lib/api/types/data-contracts";
import { useLabelStore } from "~~/stores/labels";
import { useLocationStore } from "~~/stores/locations";
import MdiPackageVariant from "~icons/mdi/package-variant";
import MdiPackageVariantClosed from "~icons/mdi/package-variant-closed";
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({
modelValue: {

View file

@ -1,6 +1,9 @@
<script setup lang="ts">
import { ViewType } from "~~/composables/use-preferences";
import { ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiDotsVertical from "~icons/mdi/dots-vertical";
import MdiCardTextOutline from "~icons/mdi/card-text-outline";
import MdiTable from "~icons/mdi/table";
type Props = {
view?: ViewType;
@ -30,18 +33,18 @@
<template #description>
<div v-if="!viewSet" class="dropdown dropdown-hover dropdown-left">
<label tabindex="0" class="btn btn-ghost m-1">
<Icon name="mdi-dots-vertical" class="h-7 w-7" />
<MdiDotsVertical class="h-7 w-7" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-32">
<li>
<button @click="setViewPreference('card')">
<Icon name="mdi-card-text-outline" class="h-5 w-5" />
<MdiCardTextOutline class="h-5 w-5" />
Card
</button>
</li>
<li>
<button @click="setViewPreference('table')">
<Icon name="mdi-table" class="h-5 w-5" />
<MdiTable class="h-5 w-5" />
Table
</button>
</li>

View file

@ -19,10 +19,13 @@
>
<template v-if="typeof h === 'string'">{{ h }}</template>
<template v-else>{{ h.text }}</template>
<div :class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`">
<div
v-if="sortByProperty === h.value"
:class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`"
>
<span class="swap swap-rotate" :class="{ 'swap-active': pagination.descending }">
<Icon name="mdi-arrow-down" class="swap-on h-5 w-5" />
<Icon name="mdi-arrow-up" class="swap-off h-5 w-5" />
<MdiArrowDown class="swap-on h-5 w-5" />
<MdiArrowUp class="swap-off h-5 w-5" />
</span>
</div>
</div>
@ -50,8 +53,8 @@
<Currency :amount="d.purchasePrice" />
</template>
<template v-else-if="cell(h) === 'cell-insured'">
<Icon v-if="d.insured" name="mdi-check" class="text-green-500 h-5 w-5" />
<Icon v-else name="mdi-close" class="text-red-500 h-5 w-5" />
<MdiCheck v-if="d.insured" class="text-green-500 h-5 w-5 inline" />
<MdiClose v-else class="text-red-500 h-5 w-5 inline" />
</template>
<slot v-else :name="cell(h)" v-bind="{ item: d }">
{{ extractValue(d, h.value) }}
@ -73,6 +76,10 @@
<script setup lang="ts">
import { TableData, TableHeader } from "./Table.types";
import { ItemSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowDown from "~icons/mdi/arrow-down";
import MdiArrowUp from "~icons/mdi/arrow-up";
import MdiCheck from "~icons/mdi/check";
import MdiClose from "~icons/mdi/close";
type Props = {
items: ItemSummary[];

View file

@ -1,5 +1,7 @@
<script setup lang="ts">
import { LabelOut, LabelSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiTagOutline from "~icons/mdi/tag-outline";
export type sizes = "sm" | "md" | "lg" | "xl";
defineProps({
@ -32,8 +34,8 @@
:to="`/label/${label.id}`"
>
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
<Icon name="heroicons-arrow-right" class="mr-2 swap-on"></Icon>
<Icon name="heroicons-tag" class="mr-2 swap-off"></Icon>
<MdiArrowRight class="mr-2 swap-on" />
<MdiTagOutline class="mr-2 swap-off" />
</label>
{{ label.name }}
</NuxtLink>

View file

@ -15,7 +15,7 @@
<BaseButton class="rounded-r-none" :loading="loading" type="submit"> Create </BaseButton>
<div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" />
<MdiChevronDown class="h-5 w-5" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li>
@ -33,6 +33,7 @@
</template>
<script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({
modelValue: {
type: Boolean,

View file

@ -13,18 +13,13 @@
>
<h2 class="flex items-center justify-between gap-2">
<label class="swap swap-rotate" :class="isActive ? 'swap-active' : ''">
<Icon name="heroicons-arrow-right" class="swap-on h-6 w-6" />
<Icon name="heroicons-map-pin" class="swap-off h-6 w-6" />
<MdiArrowRight class="swap-on h-6 w-6" />
<MdiMapMarkerOutline class="swap-off h-6 w-6" />
</label>
<span class="mx-auto">
{{ location.name }}
</span>
<span
class="badge badge-primary h-6 badge-lg"
:class="{
'opacity-0': !hasCount,
}"
>
<span class="badge badge-primary h-6 badge-lg" :class="{ 'opacity-0': !hasCount }">
{{ count }}
</span>
</h2>
@ -34,6 +29,8 @@
<script lang="ts" setup>
import { LocationOut, LocationOutCount, LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiArrowRight from "~icons/mdi/arrow-right";
import MdiMapMarkerOutline from "~icons/mdi/map-marker-outline";
const props = defineProps({
location: {

View file

@ -16,7 +16,7 @@
<BaseButton class="rounded-r-none" type="submit" :loading="loading"> Create </BaseButton>
<div class="dropdown dropdown-top">
<label tabindex="0" class="btn rounded-l-none rounded-r-xl">
<Icon class="h-5 w-5" name="mdi-chevron-down" />
<MdiChevronDown class="h-5 w-5" />
</label>
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-64 right-0">
<li>
@ -35,6 +35,7 @@
<script setup lang="ts">
import { LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiChevronDown from "~icons/mdi/chevron-down";
const props = defineProps({
modelValue: {
type: Boolean,

View file

@ -8,7 +8,7 @@
v-if="selected"
:class="['absolute inset-y-0 right-0 flex items-center pr-4', active ? 'text-white' : 'text-primary']"
>
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" />
<MdiCheck class="h-5 w-5" aria-hidden="true" />
</span>
</div>
<div v-if="cast(item.value).name != cast(item.value).treeString" class="text-xs mt-1">
@ -22,6 +22,7 @@
<script lang="ts" setup>
import { FlatTreeItem, useFlatLocations } from "~~/composables/use-location-helpers";
import { LocationSummary } from "~~/lib/api/types/data-contracts";
import MdiCheck from "~icons/mdi/check";
type Props = {
modelValue?: LocationSummary | null;

View file

@ -1,6 +1,10 @@
<script setup lang="ts">
import { useTreeState } from "./tree-state";
import { TreeItem } from "~~/lib/api/types/data-contracts";
import MdiChevronDown from "~icons/mdi/chevron-down";
import MdiChevronRight from "~icons/mdi/chevron-right";
import MdiMapMarker from "~icons/mdi/map-marker";
import MdiPackageVariant from "~icons/mdi/package-variant";
type Props = {
treeId: string;
@ -56,12 +60,12 @@
'swap-active': openRef,
}"
>
<Icon name="mdi-chevron-right" class="h-6 w-6 swap-off" />
<Icon name="mdi-chevron-down" class="h-6 w-6 swap-on" />
<MdiChevronRight name="mdi-chevron-right" class="h-6 w-6 swap-off" />
<MdiChevronDown name="mdi-chevron-down" class="h-6 w-6 swap-on" />
</label>
</div>
<Icon v-if="item.type === 'location'" name="mdi-map-marker" class="h-4 w-4" />
<Icon v-else name="mdi-package-variant" class="h-4 w-4" />
<MdiMapMarker v-if="item.type === 'location'" class="h-4 w-4" />
<MdiPackageVariant v-else class="h-4 w-4" />
<NuxtLink class="hover:link text-lg" :to="link" @click.stop>{{ item.name }} </NuxtLink>
</div>
<div v-if="openRef" class="ml-4">

View file

@ -1,7 +1,7 @@
<template>
<div ref="el" class="dropdown" :class="{ 'dropdown-open': dropdownOpen }">
<button ref="btn" tabindex="0" class="btn btn-xs" @click="toggle">
{{ label }} {{ len }} <Icon name="mdi-chevron-down" class="h-4 w-4" />
{{ label }} {{ len }} <MdiChevronDown class="h-4 w-4" />
</button>
<div tabindex="0" class="dropdown-content mt-1 w-64 shadow bg-base-100 rounded-md">
<div class="pt-4 px-4 shadow-sm mb-1">
@ -39,6 +39,7 @@
</template>
<script setup lang="ts">
import MdiChevronDown from "~icons/mdi/chevron-down";
type Props = {
label: string;
options: any[];

View file

@ -6,17 +6,15 @@
'swap-active': copied,
}"
>
<Icon
<MdiContentCopy
class="swap-off"
name="mdi-content-copy"
:style="{
height: `${iconSize}px`,
width: `${iconSize}px`,
}"
/>
<Icon
<MdiClipboard
class="swap-on"
name="mdi-clipboard"
:style="{
height: `${iconSize}px`,
width: `${iconSize}px`,
@ -27,6 +25,9 @@
</template>
<script setup lang="ts">
import MdiContentCopy from "~icons/mdi/content-copy";
import MdiClipboard from "~icons/mdi/clipboard";
const props = defineProps({
text: {
type: String as () => string,
@ -51,5 +52,3 @@
}, 1000);
}
</script>
<style scoped></style>

View file

@ -16,7 +16,7 @@
<template v-else-if="detail.type === 'link'">
<div class="tooltip tooltip-primary tooltip-right" :data-tip="detail.href">
<a class="btn btn-primary btn-xs" :href="detail.href" target="_blank">
<Icon name="mdi-open-in-new" class="mr-2 swap-on"></Icon>
<MdiOpenInNew class="mr-2 swap-on" />
{{ detail.text }}
</a>
</div>
@ -51,6 +51,7 @@
<script setup lang="ts">
import type { AnyDetail, Detail } from "./types";
import MdiOpenInNew from "~icons/mdi/open-in-new";
defineProps({
details: {

View file

@ -2,7 +2,7 @@
<div class="dropdown dropdown-left">
<slot>
<label tabindex="0" class="btn btn-circle btn-sm">
<Icon name="mdi-qrcode" />
<MdiQrcode />
</label>
</slot>
<div tabindex="0" class="card compact dropdown-content shadow-lg bg-base-100 rounded-box w-64">
@ -16,6 +16,7 @@
<script setup lang="ts">
import { route } from "../../lib/api/base";
import MdiQrcode from "~icons/mdi/qrcode";
function getQRCodeUrl(): string {
const currentURL = window.location.href;