mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-20 06:51:46 +01:00
feat: migrate to @egoist/tailwindcss-icons
This commit is contained in:
@@ -6,14 +6,14 @@
|
||||
:aria-label="ariaLabel"
|
||||
v-bind="buttonProps"
|
||||
>
|
||||
<IconCSS v-if="isLeading && leadingIconName" :name="leadingIconName" :class="leadingIconClass" aria-hidden="true" />
|
||||
<Icon v-if="isLeading && leadingIconName" :name="leadingIconName" :class="leadingIconClass" aria-hidden="true" />
|
||||
<slot>
|
||||
<span :class="[truncate ? 'text-left break-all line-clamp-1' : '', compact ? 'hidden sm:block' : '']">
|
||||
<span :class="[labelCompact && 'hidden sm:block']">{{ label }}</span>
|
||||
<span v-if="labelCompact" class="sm:hidden">{{ labelCompact }}</span>
|
||||
</span>
|
||||
</slot>
|
||||
<IconCSS v-if="isTrailing && trailingIconName" :name="trailingIconName" :class="trailingIconClass" aria-hidden="true" />
|
||||
<Icon v-if="isTrailing && trailingIconName" :name="trailingIconName" :class="trailingIconClass" aria-hidden="true" />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
@@ -22,6 +22,7 @@ import { ref, computed, useSlots } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import type { RouteLocationNormalized, RouteLocationRaw } from 'vue-router'
|
||||
import NuxtLink from '#app/components/nuxt-link'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import { classNames } from '../../utils'
|
||||
import $ui from '#build/ui'
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
@click="item.click"
|
||||
>
|
||||
<slot :name="item.slot" :item="item">
|
||||
<IconCSS v-if="item.icon" :name="item.icon" :class="[itemIconClass, item.iconClass]" />
|
||||
<Icon v-if="item.icon" :name="item.icon" :class="[itemIconClass, item.iconClass]" />
|
||||
<Avatar v-if="item.avatar" v-bind="{ size: 'xxs', ...item.avatar }" :class="itemAvatarClass" />
|
||||
|
||||
<span class="truncate">{{ item.label }}</span>
|
||||
@@ -57,6 +57,7 @@ import type { RouteLocationNormalized } from 'vue-router'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { defu } from 'defu'
|
||||
import NuxtLink from '#app/components/nuxt-link'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import Avatar from '../elements/Avatar.vue'
|
||||
import { classNames, omit } from '../../utils'
|
||||
import { usePopper } from '../../composables/usePopper'
|
||||
|
||||
16
src/runtime/components/elements/Icon.vue
Normal file
16
src/runtime/components/elements/Icon.vue
Normal file
@@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<span :class="name" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default { name: 'UIcon' }
|
||||
</script>
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="rounded-md p-4" :class="variantClass">
|
||||
<div class="flex">
|
||||
<div class="flex-shrink-0">
|
||||
<IconCSS v-if="iconName" :name="iconName" :class="iconClass" class="h-5 w-5" />
|
||||
<div class="inline-flex flex-shrink-0">
|
||||
<Icon v-if="iconName" :name="iconName" :class="iconClass" class="h-5 w-5" />
|
||||
</div>
|
||||
<div class="ml-3 flex-1 md:flex md:justify-between">
|
||||
<p v-if="title" class="text-sm leading-5" :class="titleClass">
|
||||
@@ -27,6 +27,7 @@
|
||||
import { computed } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import type { RouteLocationNormalized } from 'vue-router'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
|
||||
const props = defineProps({
|
||||
variant: {
|
||||
@@ -56,10 +57,10 @@ const props = defineProps({
|
||||
|
||||
const iconName = computed(() => {
|
||||
return ({
|
||||
info: 'heroicons-solid:information-circle',
|
||||
warning: 'heroicons-solid:exclamation',
|
||||
error: 'heroicons-solid:x-circle',
|
||||
success: 'heroicons-solid:check-circle'
|
||||
info: 'i-heroicons-information-circle',
|
||||
warning: 'i-heroicons-exclamation',
|
||||
error: 'i-heroicons-x-circle',
|
||||
success: 'i-heroicons-check-circle'
|
||||
})[props.variant]
|
||||
})
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<Modal v-model="isOpen" :appear="appear" class="w-full" @close="onClose">
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div v-if="icon" :class="iconWrapperClass" class="mx-auto flex-shrink-0 flex items-center justify-center rounded-full sm:mx-0">
|
||||
<IconCSS :name="icon" :class="iconClass" />
|
||||
<Icon :name="icon" :class="iconClass" />
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left space-y-2">
|
||||
<DialogTitle v-if="title" as="h3" :class="titleClass">
|
||||
@@ -23,6 +23,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { DialogTitle, DialogDescription } from '@headlessui/vue'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import Modal from '../overlays/Modal.vue'
|
||||
import Button from '../elements/Button.vue'
|
||||
import $ui from '#build/ui'
|
||||
@@ -54,7 +55,7 @@ const props = defineProps({
|
||||
},
|
||||
titleClass: {
|
||||
type: String,
|
||||
default: () => $ui.alertDialog.icon.title
|
||||
default: () => $ui.alertDialog.title
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
|
||||
@@ -19,16 +19,17 @@
|
||||
>
|
||||
<slot />
|
||||
<div v-if="isLeading" :class="iconLeadingWrapperClass">
|
||||
<IconCSS v-if="iconName" :name="iconName" :class="iconClass" />
|
||||
<Icon v-if="iconName" :name="iconName" :class="iconClass" />
|
||||
</div>
|
||||
<div v-if="isTrailing" :class="iconTrailingWrapperClass">
|
||||
<IconCSS v-if="iconName" :name="iconName" :class="iconClass" />
|
||||
<Icon v-if="iconName" :name="iconName" :class="iconClass" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import { classNames } from '../../utils'
|
||||
import $ui from '#build/ui'
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</select>
|
||||
|
||||
<div v-if="icon" :class="iconWrapperClass">
|
||||
<IconCSS :name="icon" :class="iconClass" />
|
||||
<Icon :name="icon" :class="iconClass" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -46,6 +46,7 @@
|
||||
import { computed } from 'vue'
|
||||
import { get } from 'lodash-es'
|
||||
import { classNames } from '../../utils'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import $ui from '#build/ui'
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</slot>
|
||||
<slot name="icon">
|
||||
<span :class="iconWrapperClass">
|
||||
<IconCSS v-if="icon" :name="icon" :class="iconClass" aria-hidden="true" />
|
||||
<Icon v-if="icon" :name="icon" :class="iconClass" aria-hidden="true" />
|
||||
</span>
|
||||
</slot>
|
||||
</button>
|
||||
@@ -58,7 +58,7 @@
|
||||
</div>
|
||||
|
||||
<span v-if="selected" :class="resolveOptionIconClass({ active })">
|
||||
<IconCSS v-if="listOptionIcon" :name="listOptionIcon" :class="listOptionIconSizeClass" aria-hidden="true" />
|
||||
<Icon v-if="listOptionIcon" :name="listOptionIcon" :class="listOptionIconSizeClass" aria-hidden="true" />
|
||||
</span>
|
||||
</li>
|
||||
</ComboboxOption>
|
||||
@@ -94,6 +94,7 @@ import {
|
||||
ComboboxOption,
|
||||
ComboboxInput
|
||||
} from '@headlessui/vue'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import { classNames } from '../../utils'
|
||||
import { usePopper } from '../../composables/usePopper'
|
||||
import type { PopperOptions } from '../../types'
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
>
|
||||
<span :class="[active ? containerActiveClass : containerInactiveClass, containerBaseClass]">
|
||||
<span v-if="iconOn" :class="[active ? iconActiveClass : iconInactiveClass, iconBaseClass]" aria-hidden="true">
|
||||
<IconCSS :name="iconOn" :class="iconOnClass" />
|
||||
<Icon :name="iconOn" :class="iconOnClass" />
|
||||
</span>
|
||||
<span v-if="iconOff" :class="[active ? iconInactiveClass : iconActiveClass, iconBaseClass]" aria-hidden="true">
|
||||
<IconCSS :name="iconOff" :class="iconOffClass" />
|
||||
<Icon :name="iconOff" :class="iconOffClass" />
|
||||
</span>
|
||||
</span>
|
||||
</Switch>
|
||||
@@ -17,6 +17,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { Switch } from '@headlessui/vue'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import $ui from '#build/ui'
|
||||
|
||||
const props = defineProps({
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
>
|
||||
<div :class="$ui.commandPalette.wrapper">
|
||||
<div v-show="searchable" class="relative flex items-center">
|
||||
<IconCSS v-if="inputIcon" :name="inputIcon" :class="$ui.commandPalette.input.icon.base" aria-hidden="true" />
|
||||
<Icon v-if="inputIcon" :name="inputIcon" :class="$ui.commandPalette.input.icon.base" aria-hidden="true" />
|
||||
<ComboboxInput
|
||||
ref="comboboxInput"
|
||||
:value="query"
|
||||
@@ -46,7 +46,7 @@
|
||||
</ComboboxOptions>
|
||||
|
||||
<div v-else-if="placeholder" class="flex flex-col items-center justify-center flex-1 px-6 py-14 sm:px-14">
|
||||
<IconCSS v-if="emptyIcon" :name="emptyIcon" class="w-6 h-6 mx-auto u-text-gray-400 mb-4" aria-hidden="true" />
|
||||
<Icon v-if="emptyIcon" :name="emptyIcon" class="w-6 h-6 mx-auto u-text-gray-400 mb-4" aria-hidden="true" />
|
||||
<p class="text-sm text-center u-text-gray-900">
|
||||
{{ query ? "We couldn't find any items with that term. Please try again." : "We couldn't find any items." }}
|
||||
</p>
|
||||
@@ -64,6 +64,7 @@ import { groupBy, map } from 'lodash-es'
|
||||
import { defu } from 'defu'
|
||||
import type { UseFuseOptions } from '@vueuse/integrations/useFuse'
|
||||
import type { Group, Command } from '../../types/command-palette'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import Button from '../elements/Button.vue'
|
||||
import CommandPaletteGroup from './CommandPaletteGroup.vue'
|
||||
import $ui from '#build/ui'
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
>
|
||||
<div :class="['flex justify-between select-none items-center rounded-md px-3 py-2 gap-3 relative', active && 'bg-gray-100 dark:bg-gray-800 u-text-gray-900', command.disabled ? 'cursor-not-allowed' : 'cursor-pointer']">
|
||||
<div class="flex items-center gap-2 min-w-0">
|
||||
<IconCSS v-if="command.icon" :name="command.icon" :class="['h-4 w-4 flex-shrink-0', active ? 'text-opacity-100 dark:text-opacity-100' : 'text-opacity-40 dark:text-opacity-40', command.iconClass || 'text-gray-900 dark:text-gray-50']" aria-hidden="true" />
|
||||
<Icon v-if="command.icon" :name="command.icon" :class="['h-4 w-4 flex-shrink-0', active ? 'text-opacity-100 dark:text-opacity-100' : 'text-opacity-40 dark:text-opacity-40', command.iconClass || 'text-gray-900 dark:text-gray-50']" aria-hidden="true" />
|
||||
<Avatar
|
||||
v-else-if="command.avatar"
|
||||
v-bind="{ size: 'xxxs', ...command.avatar }"
|
||||
@@ -35,7 +35,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<IconCSS v-if="selected" name="heroicons-outline:check" class="h-5 w-5 u-text-gray-900 flex-shrink-0" aria-hidden="true" />
|
||||
<Icon v-if="selected" :name="$ui.commandPalette.option.selected.icon.name" class="h-5 w-5 u-text-gray-900 flex-shrink-0" aria-hidden="true" />
|
||||
<slot v-else-if="active && (group.active || $slots[`${group.key}-active`])" :name="`${group.key}-active`" :group="group" :command="command">
|
||||
<span v-if="group.active" class="flex-shrink-0 u-text-gray-500">{{ group.active }}</span>
|
||||
</slot>
|
||||
@@ -54,8 +54,10 @@
|
||||
<script setup lang="ts">
|
||||
import { ComboboxOption } from '@headlessui/vue'
|
||||
import type { PropType } from 'vue'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import Avatar from '../elements/Avatar.vue'
|
||||
import type { Group } from '../../types/command-palette'
|
||||
import $ui from '#build/ui'
|
||||
|
||||
defineProps({
|
||||
group: {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
/>
|
||||
</slot>
|
||||
<slot name="icon" :link="link" :is-active="isActive">
|
||||
<IconCSS
|
||||
<Icon
|
||||
v-if="link.icon"
|
||||
:name="link.icon"
|
||||
:class="[iconBaseClass, link.label && iconSpacingClass, isActive ? iconActiveClass : iconInactiveClass, link.iconClass]"
|
||||
@@ -40,6 +40,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { PropType } from 'vue'
|
||||
import type { RouteLocationNormalized } from 'vue-router'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import Link from '../elements/Link.vue'
|
||||
import Avatar from '../elements/Avatar.vue'
|
||||
import type { Avatar as AvatarType } from '../../types/avatar'
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="p-4">
|
||||
<div class="flex gap-3" :class="{ 'items-start': description, 'items-center': !description }">
|
||||
<div v-if="iconName" class="flex-shrink-0">
|
||||
<IconCSS :name="iconName" :class="iconClass" />
|
||||
<Icon :name="iconName" :class="iconClass" />
|
||||
</div>
|
||||
<div class="w-0 flex-1">
|
||||
<p class="text-sm font-medium u-text-gray-900">
|
||||
@@ -33,11 +33,11 @@
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="transition duration-150 ease-in-out u-text-gray-400 focus:outline-none hover:u-text-gray-500 focus:u-text-gray-500"
|
||||
class="inline-flex transition duration-150 ease-in-out u-text-gray-400 focus:outline-none hover:u-text-gray-500 focus:u-text-gray-500"
|
||||
@click.stop="onClose"
|
||||
>
|
||||
<span class="sr-only">Close</span>
|
||||
<IconCSS name="heroicons-solid:x" class="w-5 h-5" />
|
||||
<Icon :name="$ui.notification.close.icon.name" class="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -53,6 +53,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, onMounted, onUnmounted, watchEffect } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import Icon from '../elements/Icon.vue'
|
||||
import { useTimer } from '../../composables/useTimer'
|
||||
import { classNames } from '../../utils'
|
||||
import type { ToastNotificationAction } from '../../types'
|
||||
|
||||
@@ -48,7 +48,7 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
},
|
||||
icon: {
|
||||
base: 'flex-shrink-0',
|
||||
loading: 'heroicons-outline:refresh',
|
||||
loading: 'i-heroicons-arrow-path',
|
||||
size: {
|
||||
xxs: 'h-3.5 w-3.5',
|
||||
xs: 'h-4 w-4',
|
||||
@@ -168,7 +168,7 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
},
|
||||
icon: {
|
||||
base: 'u-text-gray-400',
|
||||
loading: 'heroicons-outline:refresh',
|
||||
loading: 'i-heroicons-arrow-path',
|
||||
size: {
|
||||
xxs: 'h-3 w-3',
|
||||
xs: 'h-4 w-4',
|
||||
@@ -215,7 +215,7 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
wrapper: 'relative',
|
||||
base: `${select.base} text-left cursor-default`,
|
||||
icon: {
|
||||
name: 'heroicons-solid:selector',
|
||||
name: 'i-heroicons-chevron-up-down-20-solid',
|
||||
...select.icon
|
||||
},
|
||||
list: {
|
||||
@@ -233,7 +233,7 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
disabled: 'cursor-not-allowed opacity-50',
|
||||
empty: 'text-sm u-text-gray-400 px-4 py-2',
|
||||
icon: {
|
||||
name: 'heroicons-solid:check',
|
||||
name: 'i-heroicons-check-20-solid',
|
||||
base: 'absolute inset-y-0 right-0 flex items-center pr-4',
|
||||
active: 'text-white',
|
||||
inactive: 'text-primary-600',
|
||||
@@ -355,11 +355,11 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
|
||||
const alertDialog = {
|
||||
icon: {
|
||||
wrapper: 'h-12 w-12 sm:h-10 sm:w-10 bg-primary-100',
|
||||
base: 'text-primary-600'
|
||||
wrapper: 'mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-primary-100 sm:mx-0 sm:h-10 sm:w-10',
|
||||
base: 'h-6 w-6 text-primary-600'
|
||||
},
|
||||
title: 'text-lg leading-6 font-medium text-gray-900',
|
||||
description: 'text-sm text-gray-500'
|
||||
title: 'text-lg leading-6 font-medium u-text-gray-900',
|
||||
description: 'text-sm u-text-gray-500'
|
||||
}
|
||||
|
||||
const dropdown = {
|
||||
@@ -483,10 +483,10 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
rounded: 'rounded-lg',
|
||||
ring: 'ring-1 u-ring-gray-200',
|
||||
type: {
|
||||
info: 'heroicons-outline:information-circle',
|
||||
success: 'heroicons-outline:check-circle',
|
||||
warning: 'heroicons-outline:exclamation-circle',
|
||||
error: 'heroicons-outline:x-circle'
|
||||
info: 'i-heroicons-information-circle',
|
||||
success: 'i-heroicons-check-circle',
|
||||
warning: 'i-heroicons-exclamation-circle',
|
||||
error: 'i-heroicons-x-circle'
|
||||
},
|
||||
icon: {
|
||||
base: 'w-6 h-6',
|
||||
@@ -497,6 +497,11 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
error: 'text-red-400'
|
||||
}
|
||||
},
|
||||
close: {
|
||||
icon: {
|
||||
name: 'i-heroicons-x-mark-20-solid'
|
||||
}
|
||||
},
|
||||
transition: {
|
||||
enterActiveClass: 'transform ease-out duration-300 transition',
|
||||
enterFromClass: 'translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2',
|
||||
@@ -572,7 +577,7 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
base: 'w-full h-12 pr-4 placeholder-gray-400 dark:placeholder-gray-500 bg-transparent border-0 pl-[3.25rem] u-text-gray-900 focus:ring-0 sm:text-sm',
|
||||
icon: {
|
||||
base: 'pointer-events-none absolute top-3.5 left-5 h-5 w-5 u-text-gray-400',
|
||||
name: 'heroicons-outline:search'
|
||||
name: 'i-heroicons-magnifying-glass'
|
||||
},
|
||||
close: {
|
||||
base: 'absolute right-2',
|
||||
@@ -585,7 +590,14 @@ export default function defaultPreset (variantColors: string[]) {
|
||||
},
|
||||
empty: {
|
||||
icon: {
|
||||
name: 'heroicons-outline:search'
|
||||
name: 'i-heroicons-magnifying-glass'
|
||||
}
|
||||
},
|
||||
option: {
|
||||
selected: {
|
||||
icon: {
|
||||
name: 'i-heroicons-check-20-solid'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user