feat(admin): back the SPA icon picker with the server catalog
FaIconPicker drops its duplicated hard-coded FA subset and loads GET /aksrt/v1/icons/catalog: full solid/regular/brands sets, the built-in zibsvg sprite tab and an inline custom SVG tab. Props/emit surface is unchanged; the system-notice title icon schema drift (input vs icon) is fixed on the JS side.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Icon value helpers shared by admin UI.
|
||||
*
|
||||
* Supported stored formats:
|
||||
* "fa fas fa-star" — FA5 class string
|
||||
* "zibsvg-hot" — theme built-in SVG sprite key (window.aksrt_svgs)
|
||||
* "customsvg-<svg>" — inline user SVG markup
|
||||
*/
|
||||
|
||||
/** Clean pasted SVG markup: strip authoring leftovers, reject unsafe content. */
|
||||
export function cleanSvg(raw) {
|
||||
const text = String(raw || '').trim()
|
||||
if (!text) return ''
|
||||
let doc
|
||||
try {
|
||||
doc = new DOMParser().parseFromString(text, 'image/svg+xml')
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
if (doc.querySelector('parsererror')) return ''
|
||||
const svg = doc.querySelector('svg')
|
||||
if (!svg || svg.querySelector('script, foreignObject, animate')) return ''
|
||||
;['class', 'id', 'style', 't', 'version', 'p-id'].forEach((attr) => svg.removeAttribute(attr))
|
||||
Array.from(svg.attributes).forEach((attr) => {
|
||||
if (attr.name.indexOf('data-') === 0) svg.removeAttribute(attr.name)
|
||||
})
|
||||
const keep = new XMLSerializer().serializeToString(svg)
|
||||
return /<path|<use|<g\b|<circle|<rect|<polygon|<ellipse|<line/i.test(keep) ? keep : ''
|
||||
}
|
||||
|
||||
export function isFaValue(value) {
|
||||
return /^fa[\s-]/.test(String(value || '').trim())
|
||||
}
|
||||
|
||||
export function isZibsvgValue(value) {
|
||||
return String(value || '').trim().startsWith('zibsvg-')
|
||||
}
|
||||
|
||||
export function isCustomSvgValue(value) {
|
||||
return String(value || '').trim().startsWith('customsvg-')
|
||||
}
|
||||
|
||||
/** Sprite key of a zibsvg value, e.g. "zibsvg-hot" → "hot". */
|
||||
export function zibsvgKey(value) {
|
||||
return String(value || '')
|
||||
.trim()
|
||||
.slice(7)
|
||||
.replace(/[^a-zA-Z0-9_-]/g, '')
|
||||
}
|
||||
|
||||
/** Inline markup for a zibsvg sprite preview (sprite injected by svg-icon.js). */
|
||||
export function zibsvgMarkup(value) {
|
||||
const key = zibsvgKey(value)
|
||||
return key ? `<svg class="icon" aria-hidden="true"><use xlink:href="#icon-${key}"></use></svg>` : ''
|
||||
}
|
||||
|
||||
/** Value of a picker selection composed from a catalog group + icon name. */
|
||||
export function composeIconValue(group, name) {
|
||||
if (group.type === 'fa') return `fa ${group.id} fa-${name}`
|
||||
if (group.type === 'svg') return `zibsvg-${name}`
|
||||
return String(name || '')
|
||||
}
|
||||
Reference in New Issue
Block a user