Skip to content

Commit f851b6a

Browse files
committedJan 15, 2025·
feat(plugin-icon): add sizing prop for component
1 parent e8cc785 commit f851b6a

File tree

4 files changed

+89
-35
lines changed

4 files changed

+89
-35
lines changed
 

‎docs/plugins/features/icon.md

+10
Original file line numberDiff line numberDiff line change
@@ -305,3 +305,13 @@ Images links are supported with any icon types (relative links are NOT supported
305305
- Type: `string`
306306
- Default: `-0.125em`
307307
- Details: Vertical alignment of the icon.
308+
309+
### sizing
310+
311+
- Type: `'width' | 'height' | 'both'`
312+
- Default: `'height'`
313+
- Details: Icon size adjustment method.
314+
315+
- `width`: Set width only
316+
- `height`: Set height only
317+
- `both`: Set width and height

‎docs/zh/plugins/features/icon.md

+10
Original file line numberDiff line numberDiff line change
@@ -296,3 +296,13 @@ export default {
296296
- 类型:`string`
297297
- 默认值:`-0.125em`
298298
- 详情: 图标垂直对齐方式
299+
300+
### sizing
301+
302+
- 类型:`'width' | 'height' | 'both'`
303+
- 默认值:`'height'`
304+
- 详情: 图标尺寸调整方式
305+
306+
- `width`:仅设置宽度
307+
- `height`:仅设置高度
308+
- `both`:设置宽度和高度

‎plugins/features/plugin-icon/src/client/components/VPIcon.ts

+44-29
Original file line numberDiff line numberDiff line change
@@ -58,50 +58,67 @@ export const VPIcon = defineComponent({
5858
type: String,
5959
default: '',
6060
},
61+
62+
/**
63+
* Icon sizing
64+
*
65+
* 图标尺寸
66+
*
67+
* @default 'height' in main content, and 'both' in others
68+
*/
69+
sizing: {
70+
type: String as PropType<'both' | 'height' | 'width' | undefined>,
71+
default: 'height',
72+
},
6173
},
6274

6375
setup(props) {
64-
const style = computed(() => {
76+
const imageLink = computed(() =>
77+
isLinkHttp(props.icon)
78+
? props.icon
79+
: isLinkAbsolute(props.icon)
80+
? withBase(props.icon)
81+
: null,
82+
)
83+
84+
const attrs = computed(() => {
85+
const attrsObject: Record<string, unknown> = {}
6586
const styleObject: CSSProperties = {}
87+
const { type, verticalAlign, size, sizing } = props
6688

67-
if (props.color) styleObject.color = props.color
89+
if (size)
90+
styleObject['--icon-size'] = Number.isNaN(Number(size))
91+
? (size as string)
92+
: `${size}px`
93+
if (verticalAlign) styleObject['--icon-vertical-align'] = verticalAlign
6894

69-
if (props.size)
70-
styleObject.fontSize = Number.isNaN(Number(props.size))
71-
? (props.size as string)
72-
: `${props.size}px`
73-
if (props.verticalAlign) styleObject.verticalAlign = props.verticalAlign
95+
if (type === 'iconify') {
96+
if (sizing !== 'height') attrsObject.width = props.size || '1em'
97+
if (sizing !== 'width') attrsObject.height = props.size || '1em'
98+
}
7499

75-
return keys(styleObject).length ? styleObject : null
100+
if (props.sizing) attrsObject.sizing = props.sizing
101+
if (keys(styleObject).length) attrsObject.style = styleObject
102+
103+
return attrsObject
76104
})
77105

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

81109
return (): VNode | null => {
82-
const { type, icon, prefix } = props
110+
const { type, icon, prefix, sizing } = props
83111

84112
if (!icon) return null
85113

86-
if (isLinkHttp(icon)) {
114+
if (imageLink.value) {
87115
return h('img', {
88116
'class': 'vp-icon',
89-
'src': icon,
117+
'src': imageLink.value,
90118
'alt': '',
91119
'aria-hidden': '',
92120
'no-view': '',
93-
'style': style.value,
94-
})
95-
}
96-
97-
if (isLinkAbsolute(icon)) {
98-
return h('img', {
99-
'class': 'vp-icon',
100-
'src': withBase(icon),
101-
'alt': '',
102-
'aria-hidden': '',
103-
'no-view': '',
104-
'style': style.value,
121+
...attrs.value,
105122
})
106123
}
107124

@@ -111,8 +128,7 @@ export const VPIcon = defineComponent({
111128
class: 'vp-icon',
112129
// if a icon set is provided, do not add prefix
113130
icon: icon.includes(':') ? icon : `${prefix}${icon}`,
114-
inline: '',
115-
style: style.value,
131+
...attrs.value,
116132
})
117133
}
118134

@@ -125,15 +141,14 @@ export const VPIcon = defineComponent({
125141
key: icon,
126142
class: [
127143
'vp-icon',
128-
129144
// declare icon type
130145
iconType.length === 1
131146
? `fa${iconType}`
132147
: appendFontawesomePrefix(iconType),
133-
134148
...rest.split(' ').map(appendFontawesomePrefix),
149+
sizing === 'height' ? '' : 'fa-fw',
135150
],
136-
style: style.value,
151+
...attrs.value,
137152
})
138153
}
139154

@@ -144,7 +159,7 @@ export const VPIcon = defineComponent({
144159
// if multiple classes are provided, do not add prefix
145160
icon.includes(' ') ? icon : `${prefix}${icon}`,
146161
],
147-
style: style.value,
162+
...attrs.value,
148163
})
149164
}
150165
},
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
.vp-icon {
22
display: inline-block;
3-
width: 1em;
4-
height: 1em;
3+
4+
width: var(--icon-width, auto);
5+
height: var(--icon-height, auto);
6+
7+
font-size: var(--icon-size, 1em);
8+
line-height: 1;
9+
10+
// sizing=width
11+
&[sizing='width'] {
12+
--icon-width: 1em;
13+
}
14+
15+
// sizing=height
16+
&[sizing='height'] {
17+
--icon-height: 1em;
18+
}
19+
20+
// sizing=both
21+
&[sizing='both'] {
22+
--icon-width: 1em;
23+
--icon-height: 1em;
24+
}
525

626
&:is(i) {
7-
font-size: 1em;
8-
line-height: 1;
27+
vertical-align: var(--icon-vertical-align);
928
}
1029

11-
&:not(iconify-icon, i) {
12-
vertical-align: -0.125em;
30+
&:not(i) {
31+
vertical-align: var(--icon-vertical-align, -0.125em);
1332
}
1433
}

0 commit comments

Comments
 (0)
Please sign in to comment.