mirror of
https://github.com/gromlab-ru/svg-sprites.git
synced 2026-07-22 04:40:17 +03:00
feat: перейти на изолированный контракт генерации
- добавлены независимые adapters для шести exact modes - runtime переведён на JavaScript с отдельными декларациями - generated output перенесён в .svg-sprite - удалены legacy pipeline и встроенный preview
This commit is contained in:
70
src/core/compiled-artifact.ts
Normal file
70
src/core/compiled-artifact.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { getSpriteShapeId } from '../shape-id.js'
|
||||
import type { SpriteFormat } from '../types.js'
|
||||
|
||||
export type CompiledIconColor = {
|
||||
readonly variable: string
|
||||
readonly fallback: string
|
||||
}
|
||||
|
||||
export type CompiledIcon = {
|
||||
readonly name: string
|
||||
readonly id: string
|
||||
readonly viewBox: string | null
|
||||
readonly colors: readonly CompiledIconColor[]
|
||||
}
|
||||
|
||||
export type CompiledSpriteArtifact = {
|
||||
readonly format: SpriteFormat
|
||||
readonly bytes: Uint8Array
|
||||
readonly icons: readonly CompiledIcon[]
|
||||
}
|
||||
|
||||
function extractColors(fragment: string): CompiledIconColor[] {
|
||||
const colors = new Map<string, string>()
|
||||
const regex = /var\((--icon-color-\d+),\s*((?:[^()]|\([^()]*\))*)\)/g
|
||||
let match: RegExpExecArray | null
|
||||
|
||||
while ((match = regex.exec(fragment)) !== null) {
|
||||
if (!colors.has(match[1])) colors.set(match[1], match[2].trim())
|
||||
}
|
||||
|
||||
return [...colors].map(([variable, fallback]) => ({ variable, fallback }))
|
||||
}
|
||||
|
||||
/** Преобразует compiled SVG в нейтральный artifact для adapter codegen. */
|
||||
export function createCompiledSpriteArtifact(
|
||||
bytes: Uint8Array,
|
||||
iconNames: readonly string[],
|
||||
format: SpriteFormat,
|
||||
): CompiledSpriteArtifact {
|
||||
const shapes = new Map<string, { viewBox: string | null; fragment: string }>()
|
||||
const content = new TextDecoder().decode(bytes)
|
||||
const shapeRegex = /<(symbol|svg)\b((?=[^>]*\bid="[^"]+")[^>]*)>[\s\S]*?<\/\1>/g
|
||||
let match: RegExpExecArray | null
|
||||
|
||||
while ((match = shapeRegex.exec(content)) !== null) {
|
||||
const attributes = match[2]
|
||||
const id = attributes.match(/\bid="([^"]+)"/)?.[1]
|
||||
if (!id) continue
|
||||
|
||||
shapes.set(id, {
|
||||
viewBox: attributes.match(/\bviewBox="([^"]+)"/)?.[1] ?? null,
|
||||
fragment: match[0],
|
||||
})
|
||||
}
|
||||
|
||||
const icons = iconNames.map((name) => {
|
||||
const id = getSpriteShapeId(name)
|
||||
const shape = shapes.get(id)
|
||||
if (!shape) throw new Error(`Cannot find SVG shape "${id}" for icon "${name}".`)
|
||||
|
||||
return {
|
||||
name,
|
||||
id,
|
||||
viewBox: shape.viewBox,
|
||||
colors: extractColors(shape.fragment),
|
||||
}
|
||||
})
|
||||
|
||||
return { format, bytes, icons }
|
||||
}
|
||||
Reference in New Issue
Block a user