Skip to content

Commit

Permalink
feat(plugin-icon): add sizing prop for component
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Hope committed Jan 15, 2025
1 parent e8cc785 commit f851b6a
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 35 deletions.
10 changes: 10 additions & 0 deletions docs/plugins/features/icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,13 @@ Images links are supported with any icon types (relative links are NOT supported
- Type: `string`
- Default: `-0.125em`
- Details: Vertical alignment of the icon.
### sizing
- Type: `'width' | 'height' | 'both'`
- Default: `'height'`
- Details: Icon size adjustment method.
- `width`: Set width only
- `height`: Set height only
- `both`: Set width and height
10 changes: 10 additions & 0 deletions docs/zh/plugins/features/icon.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,13 @@ export default {
- 类型:`string`
- 默认值:`-0.125em`
- 详情: 图标垂直对齐方式
### sizing
- 类型:`'width' | 'height' | 'both'`
- 默认值:`'height'`
- 详情: 图标尺寸调整方式
- `width`:仅设置宽度
- `height`:仅设置高度
- `both`:设置宽度和高度
73 changes: 44 additions & 29 deletions plugins/features/plugin-icon/src/client/components/VPIcon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,50 +58,67 @@ export const VPIcon = defineComponent({
type: String,
default: '',
},

/**
* Icon sizing
*
* 图标尺寸
*
* @default 'height' in main content, and 'both' in others
*/
sizing: {
type: String as PropType<'both' | 'height' | 'width' | undefined>,
default: 'height',
},
},

setup(props) {
const style = computed(() => {
const imageLink = computed(() =>
isLinkHttp(props.icon)
? props.icon
: isLinkAbsolute(props.icon)
? withBase(props.icon)
: null,
)

const attrs = computed(() => {
const attrsObject: Record<string, unknown> = {}
const styleObject: CSSProperties = {}
const { type, verticalAlign, size, sizing } = props

if (props.color) styleObject.color = props.color
if (size)
styleObject['--icon-size'] = Number.isNaN(Number(size))
? (size as string)
: `${size}px`
if (verticalAlign) styleObject['--icon-vertical-align'] = verticalAlign

if (props.size)
styleObject.fontSize = Number.isNaN(Number(props.size))
? (props.size as string)
: `${props.size}px`
if (props.verticalAlign) styleObject.verticalAlign = props.verticalAlign
if (type === 'iconify') {
if (sizing !== 'height') attrsObject.width = props.size || '1em'
if (sizing !== 'width') attrsObject.height = props.size || '1em'
}

return keys(styleObject).length ? styleObject : null
if (props.sizing) attrsObject.sizing = props.sizing
if (keys(styleObject).length) attrsObject.style = styleObject

return attrsObject
})

const appendFontawesomePrefix = (icon: string): string =>
icon.includes('fa-') || /^fa.$/.test(icon) ? icon : `fa-${icon}`

return (): VNode | null => {
const { type, icon, prefix } = props
const { type, icon, prefix, sizing } = props

if (!icon) return null

if (isLinkHttp(icon)) {
if (imageLink.value) {
return h('img', {
'class': 'vp-icon',
'src': icon,
'src': imageLink.value,
'alt': '',
'aria-hidden': '',
'no-view': '',
'style': style.value,
})
}

if (isLinkAbsolute(icon)) {
return h('img', {
'class': 'vp-icon',
'src': withBase(icon),
'alt': '',
'aria-hidden': '',
'no-view': '',
'style': style.value,
...attrs.value,
})
}

Expand All @@ -111,8 +128,7 @@ export const VPIcon = defineComponent({
class: 'vp-icon',
// if a icon set is provided, do not add prefix
icon: icon.includes(':') ? icon : `${prefix}${icon}`,
inline: '',
style: style.value,
...attrs.value,
})
}

Expand All @@ -125,15 +141,14 @@ export const VPIcon = defineComponent({
key: icon,
class: [
'vp-icon',

// declare icon type
iconType.length === 1
? `fa${iconType}`
: appendFontawesomePrefix(iconType),

...rest.split(' ').map(appendFontawesomePrefix),
sizing === 'height' ? '' : 'fa-fw',
],
style: style.value,
...attrs.value,
})
}

Expand All @@ -144,7 +159,7 @@ export const VPIcon = defineComponent({
// if multiple classes are provided, do not add prefix
icon.includes(' ') ? icon : `${prefix}${icon}`,
],
style: style.value,
...attrs.value,
})
}
},
Expand Down
31 changes: 25 additions & 6 deletions plugins/features/plugin-icon/src/client/styles/vp-icon.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,33 @@
.vp-icon {
display: inline-block;
width: 1em;
height: 1em;

width: var(--icon-width, auto);
height: var(--icon-height, auto);

font-size: var(--icon-size, 1em);
line-height: 1;

// sizing=width
&[sizing='width'] {
--icon-width: 1em;
}

// sizing=height
&[sizing='height'] {
--icon-height: 1em;
}

// sizing=both
&[sizing='both'] {
--icon-width: 1em;
--icon-height: 1em;
}

&:is(i) {
font-size: 1em;
line-height: 1;
vertical-align: var(--icon-vertical-align);
}

&:not(iconify-icon, i) {
vertical-align: -0.125em;
&:not(i) {
vertical-align: var(--icon-vertical-align, -0.125em);
}
}

0 comments on commit f851b6a

Please sign in to comment.