Skip to content

Commit 733e1bf

Browse files
authored
fix(preset-icons): add custom icon handling without unit (#5279)
1 parent e54a3ed commit 733e1bf

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

packages-presets/preset-icons/src/core.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { getEnvFlags } from '#integration/env'
1010
import icons from './collections'
1111

1212
const COLLECTION_NAME_PARTS_MAX = 3
13+
const numberWithUnitRE = /^(-?\d*(?:\.\d+)?)(px|pt|pc|%|r?(?:em|ex|lh|cap|ch|ic)|(?:[sld]?v|cq)(?:[whib]|min|max)|in|cm|mm|rpx)?$/i
1314

1415
export { IconsOptions }
1516
export { icons }
@@ -89,14 +90,23 @@ export function createPresetIcons(lookupIconLoader: (options: IconsOptions) => P
8990

9091
iconLoader = iconLoader || await lookupIconLoader(options)
9192

92-
const usedProps = {}
93+
const usedProps: Record<string, string> = {}
9394
const parsed = await parseIconWithLoader(
9495
body,
9596
iconLoader,
9697
{ ...loaderOptions, usedProps },
9798
iconifyCollectionsNames,
9899
)
99100

101+
const fallbackSize = `${scale}${unit ?? 'em'}`
102+
for (const prop of ['width', 'height']) {
103+
const value = usedProps[prop]
104+
const match = value?.match(numberWithUnitRE)
105+
106+
if (!value || (match && !match[2]))
107+
usedProps[prop] = fallbackSize
108+
}
109+
100110
if (!parsed) {
101111
if (warn && !flags.isESLint)
102112
warnOnce(`failed to load icon "${full}"`)

test/preset-icons.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,43 @@ describe('preset-icons', async () => {
8080
const { css } = await uno.generate(fixtures.join(' '), { preflights: false })
8181
await expect(css).toMatchFileSnapshot('./assets/output/preset-icons-propsProcessor.css')
8282
})
83+
84+
it('custom without unit', async () => {
85+
const uno = await createGenerator({
86+
presets: [
87+
presetIcons({
88+
collections: {
89+
custom: {
90+
foo: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"></svg>`,
91+
bar: `<svg width='32' height='32' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"></svg>`,
92+
baz: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"></svg>`,
93+
qux: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"></svg>`,
94+
},
95+
},
96+
customizations: {
97+
iconCustomizer(collection, icon, props) {
98+
if (collection === 'custom' && icon === 'baz') {
99+
props.width = 'var(--icon-size)'
100+
props.height = 'var(--icon-size)'
101+
}
102+
if (collection === 'custom' && icon === 'qux') {
103+
props.width = 'auto'
104+
props.height = 'auto'
105+
}
106+
},
107+
},
108+
}),
109+
],
110+
})
111+
112+
const { css } = await uno.generate('i-custom:foo i-custom:bar i-custom:baz i-custom:qux')
113+
114+
expect(css).toMatchInlineSnapshot(`
115+
"/* layer: icons */
116+
.i-custom\\:bar{background:url("data:image/svg+xml;utf8,%3Csvg width='32' height='32' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;width:1em;height:1em;}
117+
.i-custom\\:baz{background:url("data:image/svg+xml;utf8,%3Csvg width='var(--icon-size)' height='var(--icon-size)' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;width:var(--icon-size);height:var(--icon-size);}
118+
.i-custom\\:foo{background:url("data:image/svg+xml;utf8,%3Csvg width='1em' height='1em' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;width:1em;height:1em;}
119+
.i-custom\\:qux{background:url("data:image/svg+xml;utf8,%3Csvg width='auto' height='auto' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256'%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;width:auto;height:auto;}"
120+
`)
121+
})
83122
})

0 commit comments

Comments
 (0)
Sponsor
SponsoredKunjungi sekarang
Promo