pengzhanbo 149732520a
feat: add multiple provider support for icon, close #568 (#596)
* feat: add multiple provider support for icon

* chore: tweak

* chore: tweak
2025-05-16 11:03:41 +08:00

58 lines
1.5 KiB
TypeScript

import type { IconOptions } from '../../shared/index.js'
import { kebabCase, omit } from '@pengzhanbo/utils'
import { resolveAttrs } from '../utils/resolveAttrs.js'
export interface ResolvedIcon {
provider: Exclude<IconOptions['provider'], undefined>
size?: string | number
color?: string
name: string
extra?: string
}
const RE_SIZE = /(?<=\s|^)=(.+?)(?:\s|$)/
const RE_COLOR = /(?<=\s|^)\/(.+?)(?:\s|$)/
const RE_PROVIDER = /^(iconify|iconfont|fontawesome)\s+/
const RE_EXTRA_KEY = /(?:^|-)\d-/g
export function resolveIcon(content: string, options: IconOptions): ResolvedIcon {
let size = options.size
let color = options.color
let provider = options.provider || 'iconify'
content = content
.replace(RE_PROVIDER, (_, p) => {
provider = p
return ''
})
.replace(RE_SIZE, (_, s) => {
size = s
return ''
})
.replace(RE_COLOR, (_, c) => {
color = c
return ''
})
.trim()
const index = content.indexOf(' ')
const name = index === -1 ? content : content.slice(0, index)
const extra = index === -1 ? '' : content.slice(index + 1)
const props = { provider, size, color, name }
if (!extra) {
return props
}
const { attrs } = resolveAttrs(extra)
const info: string[] = []
const excludes: string[] = []
for (const key in attrs) {
if (attrs[key] === true) {
excludes.push(key)
info.push(kebabCase(key).replace(RE_EXTRA_KEY, m => `${m.slice(0, -1)}`))
}
}
return { ...props, extra: info.join(' '), ...omit(attrs, excludes) }
}