Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(VIcon): support SVGs with multiple paths #17098

Merged
merged 3 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/docs/src/components/examples/Example.vue
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@

if (playgroundLink.value) {
array.push({
icon: '$vuetify',
icon: '$vuetifyPlay',
path: 'edit-in-playground',
href: playgroundLink.value,
target: '_blank',
Expand Down
9 changes: 8 additions & 1 deletion packages/docs/src/plugins/vuetify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,15 @@ export const useVuetify: VuetifyPlugin = ({ app }) => {
},
aliases: {
/* eslint-disable max-len */
vuetify: 'svg:M7.26 12.28 2 3H12.53L7.26 12.28ZM14.44 3 8.22 13.98 12 20.64 22 3 14.44 3Z',
vuetify: [
'M8.2241 14.2009L12 21L22 3H14.4459L8.2241 14.2009Z',
['M7.26303 12.4733L7.00113 12L2 3H12.5261C12.5261 3 12.5261 3 12.5261 3L7.26303 12.4733Z', 0.4],
],
'vuetify-outline': 'svg:M7.26 12.47 12.53 3H2L7.26 12.47ZM14.45 3 8.22 14.2 12 21 22 3H14.45ZM18.6 5 12 16.88 10.51 14.2 15.62 5ZM7.26 8.35 5.4 5H9.13L7.26 8.35Z',
vuetifyPlay: [
'm6.376 13.184-4.11-7.192C1.505 4.66 2.467 3 4.003 3h8.532l-.953 1.576-.006.01-.396.677c-.429.732-.214 1.507.194 2.015.404.503 1.092.878 1.869.806a3.72 3.72 0 0 1 1.005.022c.276.053.434.143.523.237.138.146.38.635-.25 2.09-.893 1.63-1.553 1.722-1.847 1.677-.213-.033-.468-.158-.756-.406a4.95 4.95 0 0 1-.8-.927c-.39-.564-1.04-.84-1.66-.846-.625-.006-1.316.27-1.693.921l-.478.826-.911 1.506Z',
['M9.093 11.552c.046-.079.144-.15.32-.148a.53.53 0 0 1 .43.207c.285.414.636.847 1.046 1.2.405.35.914.662 1.516.754 1.334.205 2.502-.698 3.48-2.495l.014-.028.013-.03c.687-1.574.774-2.852-.005-3.675-.37-.391-.861-.586-1.333-.676a5.243 5.243 0 0 0-1.447-.044c-.173.016-.393-.073-.54-.257-.145-.18-.127-.316-.082-.392l.393-.672L14.287 3h5.71c1.536 0 2.499 1.659 1.737 2.992l-7.997 13.996c-.768 1.344-2.706 1.344-3.473 0l-3.037-5.314 1.377-2.278.004-.006.004-.007.481-.831Z', 0.6],
],
/* eslint-enable max-len */
},
},
Expand Down
26 changes: 21 additions & 5 deletions packages/vuetify/src/composables/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import { defineComponent, genericComponent, mergeDeep, propsFactory } from '@/ut
// Types
import type { InjectionKey, JSXComponent, PropType, Ref } from 'vue'

export type IconValue = string | JSXComponent
export const IconValue = [String, Function, Object] as PropType<IconValue>
export type IconValue =
| string
| (string | [path: string, opacity: number])[]
| JSXComponent
export const IconValue = [String, Function, Object, Array] as PropType<IconValue>

export interface IconAliases {
[name: string]: IconValue
Expand Down Expand Up @@ -92,9 +95,10 @@ export const VComponentIcon = genericComponent()({

setup (props, { slots }) {
return () => {
const Icon = props.icon as JSXComponent
return (
<props.tag>
{ props.icon ? <props.icon /> : slots.default?.() }
{ props.icon ? <Icon /> : slots.default?.() }
</props.tag>
)
}
Expand All @@ -120,7 +124,14 @@ export const VSvgIcon = defineComponent({
role="img"
aria-hidden="true"
>
<path d={ props.icon as string }></path>
{ Array.isArray(props.icon)
? props.icon.map(path => (
Array.isArray(path)
? <path d={ path[0] as string } fill-opacity={ path[1] }></path>
: <path d={ path as string }></path>
))
: <path d={ props.icon as string }></path>
}
</svg>
</props.tag>
)
Expand Down Expand Up @@ -198,7 +209,12 @@ export const useIcon = (props: Ref<string | undefined> | { icon?: IconValue }) =

if (!icon) throw new Error(`Could not find aliased icon "${iconAlias}"`)

if (typeof icon !== 'string') {
if (Array.isArray(icon)) {
return {
component: VSvgIcon,
icon,
}
} else if (typeof icon !== 'string') {
return {
component: VComponentIcon,
icon,
Expand Down