diff --git a/docs/app/components/content/examples/icon/IconSvgExample.vue b/docs/app/components/content/examples/icon/IconSvgExample.vue new file mode 100644 index 0000000000..64820133ca --- /dev/null +++ b/docs/app/components/content/examples/icon/IconSvgExample.vue @@ -0,0 +1,25 @@ + + + diff --git a/docs/content/docs/2.components/icon.md b/docs/content/docs/2.components/icon.md index a3b174febd..1c6923b602 100644 --- a/docs/content/docs/2.components/icon.md +++ b/docs/content/docs/2.components/icon.md @@ -1,5 +1,5 @@ --- -description: A component to display any icon from Iconify. +description: A component to display any icon from Iconify or another component. category: element links: - label: IcĂ´nes @@ -27,6 +27,30 @@ It's highly recommended to install the icons collections you need, read more abo ::: :: +## Examples + +### SVG + +You can also pass a Vue component into the `name` prop: + +::component-example +--- +name: 'icon-svg-example' +--- +:: + +You can define your icon components yourself, or use [`unplugin-icons`](https://github.com/unplugin/unplugin-icons) to import them directly from SVG files: + +```vue + + + +``` + ## API ### Props diff --git a/src/runtime/components/Accordion.vue b/src/runtime/components/Accordion.vue index 52af6f112b..da99b2271d 100644 --- a/src/runtime/components/Accordion.vue +++ b/src/runtime/components/Accordion.vue @@ -3,6 +3,7 @@ import type { AccordionRootProps, AccordionRootEmits } from 'reka-ui' import type { AppConfig } from '@nuxt/schema' import theme from '#build/ui/accordion' +import type { IconProps } from '../types' import type { DynamicSlots } from '../types/utils' import type { ComponentConfig } from '../types/tv' @@ -13,11 +14,11 @@ export interface AccordionItem { /** * @IconifyIcon */ - icon?: string + icon?: IconProps['name'] /** * @IconifyIcon */ - trailingIcon?: string + trailingIcon?: IconProps['name'] slot?: string content?: string /** A unique value for the accordion item. Defaults to the index. */ @@ -40,7 +41,7 @@ export interface AccordionProps extends * @defaultValue appConfig.ui.icons.chevronDown * @IconifyIcon */ - trailingIcon?: string + trailingIcon?: IconProps['name'] /** * The key used to get the label from the item. * @defaultValue 'label' diff --git a/src/runtime/components/Alert.vue b/src/runtime/components/Alert.vue index d2366dafad..1d9ab5c5c1 100644 --- a/src/runtime/components/Alert.vue +++ b/src/runtime/components/Alert.vue @@ -1,7 +1,7 @@ diff --git a/src/runtime/components/InputMenu.vue b/src/runtime/components/InputMenu.vue index 18b93353e2..1a1128a8b6 100644 --- a/src/runtime/components/InputMenu.vue +++ b/src/runtime/components/InputMenu.vue @@ -4,7 +4,7 @@ import type { ComboboxRootProps, ComboboxRootEmits, ComboboxContentProps, Combob import type { AppConfig } from '@nuxt/schema' import theme from '#build/ui/input-menu' import type { UseComponentIconsProps } from '../composables/useComponentIcons' -import type { AvatarProps, ChipProps, InputProps } from '../types' +import type { AvatarProps, ChipProps, IconProps, InputProps } from '../types' import type { AcceptableValue, ArrayOrNested, GetItemKeys, GetItemValue, GetModelValue, GetModelValueEmits, NestedItem, EmitsToProps } from '../types/utils' import type { ComponentConfig } from '../types/tv' @@ -15,7 +15,7 @@ interface _InputMenuItem { /** * @IconifyIcon */ - icon?: string + icon?: IconProps['name'] avatar?: AvatarProps chip?: ChipProps /** @@ -61,20 +61,20 @@ export interface InputMenuProps = ArrayOr * @defaultValue appConfig.ui.icons.chevronDown * @IconifyIcon */ - trailingIcon?: string + trailingIcon?: IconProps['name'] /** * The icon displayed when an item is selected. * @defaultValue appConfig.ui.icons.check * @IconifyIcon */ - selectedIcon?: string + selectedIcon?: IconProps['name'] /** * The icon displayed to delete a tag. * Works only when `multiple` is `true`. * @defaultValue appConfig.ui.icons.close * @IconifyIcon */ - deleteIcon?: string + deleteIcon?: IconProps['name'] /** * The content of the menu. * @defaultValue { side: 'bottom', sideOffset: 8, collisionPadding: 8, position: 'popper' } diff --git a/src/runtime/components/InputNumber.vue b/src/runtime/components/InputNumber.vue index 4400c4c108..a387d0fa08 100644 --- a/src/runtime/components/InputNumber.vue +++ b/src/runtime/components/InputNumber.vue @@ -2,7 +2,7 @@ import type { NumberFieldRootProps } from 'reka-ui' import type { AppConfig } from '@nuxt/schema' import theme from '#build/ui/input-number' -import type { ButtonProps } from '../types' +import type { ButtonProps, IconProps } from '../types' import type { ComponentConfig } from '../types/tv' type InputNumber = ComponentConfig @@ -35,7 +35,7 @@ export interface InputNumberProps extends Pick @@ -39,7 +39,7 @@ export interface InputTagsProps extends P * @defaultValue appConfig.ui.icons.close * @IconifyIcon */ - deleteIcon?: string + deleteIcon?: IconProps['name'] /** Highlight the ring color like a focus state. */ highlight?: boolean class?: any diff --git a/src/runtime/components/Modal.vue b/src/runtime/components/Modal.vue index 7e1c11de18..0bc75a7010 100644 --- a/src/runtime/components/Modal.vue +++ b/src/runtime/components/Modal.vue @@ -2,7 +2,7 @@ import type { DialogRootProps, DialogRootEmits, DialogContentProps, DialogContentEmits } from 'reka-ui' import type { AppConfig } from '@nuxt/schema' import theme from '#build/ui/modal' -import type { ButtonProps } from '../types' +import type { ButtonProps, IconProps } from '../types' import type { EmitsToProps } from '../types/utils' import type { ComponentConfig } from '../types/tv' @@ -44,7 +44,7 @@ export interface ModalProps extends DialogRootProps { * @defaultValue appConfig.ui.icons.close * @IconifyIcon */ - closeIcon?: string + closeIcon?: IconProps['name'] /** * When `false`, the modal will not close when clicking outside or pressing escape. * @defaultValue true diff --git a/src/runtime/components/NavigationMenu.vue b/src/runtime/components/NavigationMenu.vue index 68af27ba04..bd4e47aff0 100644 --- a/src/runtime/components/NavigationMenu.vue +++ b/src/runtime/components/NavigationMenu.vue @@ -3,7 +3,7 @@ import type { NavigationMenuRootProps, NavigationMenuRootEmits, NavigationMenuContentProps, NavigationMenuContentEmits, AccordionRootProps } from 'reka-ui' import type { AppConfig } from '@nuxt/schema' import theme from '#build/ui/navigation-menu' -import type { AvatarProps, BadgeProps, LinkProps, PopoverProps, TooltipProps } from '../types' +import type { AvatarProps, BadgeProps, IconProps, LinkProps, PopoverProps, TooltipProps } from '../types' import type { ArrayOrNested, DynamicSlots, MergeTypes, NestedItem, EmitsToProps } from '../types/utils' import type { ComponentConfig } from '../types/tv' @@ -20,7 +20,7 @@ export interface NavigationMenuItem extends Omit * @defaultValue appConfig.ui.icons.chevronDown * @IconifyIcon */ - trailingIcon?: string + trailingIcon?: IconProps['name'] /** * The icon displayed when the item is an external link. * Set to `false` to hide the external icon. * @defaultValue appConfig.ui.icons.external * @IconifyIcon */ - externalIcon?: boolean | string + externalIcon?: boolean | IconProps['name'] items?: T /** * @defaultValue 'primary' diff --git a/src/runtime/components/PageAnchors.vue b/src/runtime/components/PageAnchors.vue index 7f0aecc9e0..719d431089 100644 --- a/src/runtime/components/PageAnchors.vue +++ b/src/runtime/components/PageAnchors.vue @@ -1,7 +1,7 @@ diff --git a/src/runtime/components/prose/Collapsible.vue b/src/runtime/components/prose/Collapsible.vue index f14c0f2526..df87bc4ef6 100644 --- a/src/runtime/components/prose/Collapsible.vue +++ b/src/runtime/components/prose/Collapsible.vue @@ -1,6 +1,7 @@ @@ -11,5 +13,6 @@ defineProps()