@driftime/sanity-plugin-icon 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +341 -113
  2. package/dist/adapters-Bx_MyEX_.js +633 -0
  3. package/dist/adapters-Bx_MyEX_.js.map +1 -0
  4. package/dist/drawing-ByrcBbWB.js +50 -0
  5. package/dist/drawing-ByrcBbWB.js.map +1 -0
  6. package/dist/index.d.ts +85 -33
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +746 -443
  9. package/dist/index.js.map +1 -1
  10. package/dist/names.d.ts +8 -0
  11. package/dist/names.d.ts.map +1 -0
  12. package/dist/names.js +0 -0
  13. package/dist/next-loader.d.ts +64 -0
  14. package/dist/next-loader.d.ts.map +1 -0
  15. package/dist/next-loader.js +102 -0
  16. package/dist/next-loader.js.map +1 -0
  17. package/dist/next.d.ts +43 -0
  18. package/dist/next.d.ts.map +1 -0
  19. package/dist/next.js +51 -0
  20. package/dist/next.js.map +1 -0
  21. package/dist/nodes-DAzj56Xn.js +139 -0
  22. package/dist/nodes-DAzj56Xn.js.map +1 -0
  23. package/dist/read-worker.d.ts +1 -0
  24. package/dist/read-worker.js +23 -0
  25. package/dist/read-worker.js.map +1 -0
  26. package/dist/registry-BEEpqK3z.js +13 -0
  27. package/dist/registry-BEEpqK3z.js.map +1 -0
  28. package/dist/registry-dxVzo7ZX.js +58 -0
  29. package/dist/registry-dxVzo7ZX.js.map +1 -0
  30. package/dist/render.d.ts +8 -9
  31. package/dist/render.d.ts.map +1 -1
  32. package/dist/render.js +5 -6
  33. package/dist/render.js.map +1 -1
  34. package/dist/sets-DVh8eYeP.js +258 -0
  35. package/dist/sets-DVh8eYeP.js.map +1 -0
  36. package/dist/sets-kepuObH8.js +90 -0
  37. package/dist/sets-kepuObH8.js.map +1 -0
  38. package/dist/sets.d.ts +50 -0
  39. package/dist/sets.d.ts.map +1 -0
  40. package/dist/sets.js +14 -0
  41. package/dist/sets.js.map +1 -0
  42. package/dist/types-qlHEYDoN.d.ts +20 -0
  43. package/dist/types-qlHEYDoN.d.ts.map +1 -0
  44. package/dist/utils-COPacfAq.js +48 -0
  45. package/dist/utils-COPacfAq.js.map +1 -0
  46. package/dist/vite-ifICG8y9.d.ts +98 -0
  47. package/dist/vite-ifICG8y9.d.ts.map +1 -0
  48. package/dist/vite.d.ts +2 -0
  49. package/dist/vite.js +88 -0
  50. package/dist/vite.js.map +1 -0
  51. package/package.json +58 -30
  52. package/LICENSE +0 -21
  53. package/dist/drawing-Bo0HTICv.js +0 -120
  54. package/dist/drawing-Bo0HTICv.js.map +0 -1
  55. package/dist/types-_D2jGm25.d.ts +0 -16
  56. package/dist/types-_D2jGm25.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters-Bx_MyEX_.js","names":["createHash","isDefined","XastChild","XastElement","XastRoot","optimize","IconDrawing","IconElement","IconRoot","findDrawingProblem","IconSetIcon","SourceIcon","name","keywords","svg","ConvertedIcon","icon","root","problem","rootOnlyAttributes","Set","toReactName","replaceAll","_match","character","toUpperCase","readAttributes","attributes","Record","omitted","ReadonlySet","Object","fromEntries","entries","flatMap","value","test","has","closeOpenUrls","element","readChildren","children","child","type","trim","nested","readSvgElement","tree","find","undefined","width","replace","height","viewBox","node","filter","readDrawing","result","drawing","declared","includes","multipass","plugins","fn","enter","params","overrides","cleanupNumericValues","convertPathData","convertTransform","inlineStyles","onlyMatchedOnce","mergePaths","prefix","update","digest","slice","parseDrawing","convertIcon","source","nameWords","split","map","keyword","toLowerCase","readFile","readdir","createRequire","path","pathToFileURL","isDefined","isRecord","ElementType","createElement","renderToStaticMarkup","SourceIcon","toReactName","roundStrokeRoot","viewBox","fill","stroke","toKebabName","name","replaceAll","toLowerCase","isReact","value","isServerRenderer","isElementType","loadRenderer","root","react","requireFromProject","server","undefined","render","type","props","Record","toProps","attributes","Object","fromEntries","entries","flatMap","String","writeElementPairs","renderer","Array","isArray","create","elements","pair","index","key","length","xmlns","children","readSvgIcons","folder","files","describe","file","keywords","icons","Promise","all","map","svg","join","listSvgFiles","directory","filter","endsWith","toSorted","importPackageFile","loaded","href","createHash","readFile","readdir","path","isDefined","isRecord","InstalledPackage","name","directory","version","listPluginFiles","files","import","meta","dirname","filter","file","endsWith","toSorted","map","join","readPluginBuild","contents","Promise","all","content","hash","update","basename","digest","slice","readJson","JSON","parse","undefined","listAncestors","parent","findPackage","root","candidates","resolve","folder","manifest","published","readDeclaredPackages","Set","groups","flatMap","group","Object","keys","path","convertCase","isRecord","listSvgFiles","readSvgIcons","IconAdapter","readJson","createCustomAdapter","library","folder","label","packageName","undefined","styles","read","root","directory","resolve","files","keywords","Promise","all","join","file","name","slice","length","listed","Array","isArray","map","String","path","isDefined","isRecord","importPackageFile","isElementType","loadRenderer","toKebabName","IconAdapter","readJson","centralAdapter","library","label","packageName","undefined","packagePrefix","packageExample","styles","read","directory","root","renderer","exports","index","Promise","all","join","aliases","Object","entries","flatMap","exportName","component","startsWith","endsWith","svg","render","mode","listed","keywords","split","map","keyword","trim","name","slice","length","centralFills","const","centralRadii","centralStrokes","centralStyles","flatMap","fill","radius","map","stroke","nucleoStyles","iconLibraryStyles","central","heroicons","hugeicons","iconoir","lucide","nucleo","phosphor","tabler","path","listSvgFiles","readSvgIcons","IconAdapter","iconLibraryStyles","styleFolders","Record","outline","solid","mini","micro","heroiconsAdapter","library","label","packageName","packagePattern","styles","heroicons","read","directory","style","folder","join","files","file","name","slice","length","keywords","isDefined","importPackageFile","toKebabName","writeElementPairs","IconAdapter","iconLibraryStyles","exportSuffixes","hugeiconsAdapter","library","label","packageName","packagePattern","styles","hugeicons","read","directory","root","exports","namesByIcon","Map","exportName","value","Object","entries","set","get","flatMap","exportNames","svg","viewBox","fill","iconNames","filter","endsWith","toSorted","primary","name","replace","keywords","path","listSvgFiles","readSvgIcons","IconAdapter","iconLibraryStyles","iconoirAdapter","library","label","packageName","packagePattern","styles","iconoir","read","directory","style","folder","join","files","file","name","slice","length","keywords","path","isDefined","isRecord","roundStrokeRoot","writeElementPairs","IconAdapter","readJson","iconLibraryStyles","lucideAdapter","library","label","packageName","packagePattern","styles","lucide","read","directory","root","nodes","tags","Promise","all","join","Object","entries","flatMap","name","value","svg","keywords","Array","isArray","map","String","isDefined","importPackageFile","isElementType","loadRenderer","toKebabName","IconAdapter","findStyleSuffix","names","first","rest","length","every","name","at","shared","slice","start","search","nucleoAdapter","library","label","packageName","undefined","packagePrefix","packageExample","styles","read","directory","root","renderer","exports","components","Object","entries","flatMap","exportName","component","startsWith","const","suffix","map","svg","render","keywords","path","isRecord","importPackageFile","listSvgFiles","readSvgIcons","IconAdapter","iconLibraryStyles","readPhosphorKeywords","directory","icons","Array","isArray","Map","flatMap","icon","map","String","const","phosphorAdapter","library","label","packageName","packagePattern","styles","phosphor","read","style","folder","join","files","keywords","Promise","all","suffix","filter","file","endsWith","name","slice","length","get","path","isDefined","isRecord","roundStrokeRoot","writeElementPairs","IconAdapter","readJson","iconLibraryStyles","tablerAdapter","library","label","packageName","packagePattern","styles","tabler","read","directory","style","root","nodes","details","Promise","all","join","attributes","viewBox","fill","Object","entries","flatMap","name","value","svg","detail","undefined","tags","Array","isArray","map","String","keywords","centralAdapter","heroiconsAdapter","hugeiconsAdapter","iconoirAdapter","lucideAdapter","nucleoAdapter","phosphorAdapter","tablerAdapter","IconAdapter","iconAdapters","\"width\"","\"height\"","\"viewBox\"","\"createElement\"","\"renderToStaticMarkup\"","\"version\"","\"name\"","\"dependencies\"","\"devDependencies\"","\"peerDependencies\"","\"iconAliases\"","\"tags\""],"sources":["../src/build/convert.ts","../src/build/adapters/shared.ts","../src/build/packages.ts","../src/build/adapters/custom.ts","../src/build/adapters/central.ts","../src/lib/libraries.ts","../src/build/adapters/heroicons.ts","../src/build/adapters/hugeicons.ts","../src/build/adapters/iconoir.ts","../src/build/adapters/lucide.ts","../src/build/adapters/nucleo.ts","../src/build/adapters/phosphor.ts","../src/build/adapters/tabler.ts","../src/build/adapters/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport { isDefined } from \"@repo/lib/utils\";\nimport type { XastChild, XastElement, XastRoot } from \"svgo\";\nimport { optimize } from \"svgo\";\n\nimport type { IconDrawing, IconElement, IconRoot } from \"@/lib/nodes\";\nimport { findDrawingProblem } from \"@/lib/nodes\";\nimport type { IconSetIcon } from \"@/lib/sets\";\n\n/** An icon as read from a library, before conversion. */\nexport interface SourceIcon {\n /** Name of the icon in its library. */\n name: string;\n /** Words describing the icon, from its library. */\n keywords: string[];\n /** The icon's SVG markup. */\n svg: string;\n}\n\n/** An icon after conversion, with its own root, or why it couldn't be converted. */\nexport type ConvertedIcon =\n | { icon: IconSetIcon & { root: IconRoot }; problem?: undefined }\n | { icon?: undefined; problem: string };\n\n/** Attributes of the outer SVG that size or label it rather than draw it, since the renderer sets its own. */\nconst rootOnlyAttributes = new Set([\"class\", \"focusable\", \"height\", \"role\", \"version\", \"width\"]);\n\n/**\n * Converts an SVG attribute name to its React form, such as `stroke-width` to `strokeWidth` and `xlink:href` to\n * `xlinkHref`.\n *\n * @param name - The attribute name.\n * @returns The React name.\n */\nexport function toReactName(name: string) {\n return name.replaceAll(/[-:](?<character>[a-z])/gu, (_match, character: string) => character.toUpperCase());\n}\n\n/**\n * Converts attributes to React naming, leaving out namespaces, classes, and data and accessibility attributes, which\n * don't draw anything.\n *\n * @param attributes - The attributes.\n * @param omitted - Further attributes to leave out.\n * @returns The converted attributes.\n */\nfunction readAttributes(attributes: Record<string, string>, omitted: ReadonlySet<string> = new Set([\"class\"])) {\n return Object.fromEntries(\n Object.entries(attributes).flatMap(([name, value]) =>\n /^(?:xmlns|data-|aria-)/u.test(name) || omitted.has(name) ? [] : [[toReactName(name), value]],\n ),\n );\n}\n\n/**\n * Closes a `url(` left open at the end of each attribute value, which is how browsers read it.\n *\n * @param element - The element whose attributes to close.\n */\nfunction closeOpenUrls(element: XastElement) {\n for (const [name, value] of Object.entries(element.attributes)) {\n if (/url\\([^)]*$/u.test(value)) element.attributes[name] = `${value})`;\n }\n}\n\n/**\n * Converts SVGO's parsed children into stored elements, keeping text and dropping comments.\n *\n * @param children - The parsed children.\n * @returns The elements and text.\n */\nfunction readChildren(children: XastChild[]) {\n return children.flatMap((child): (IconElement | string)[] => {\n if (child.type === \"text\") return isDefined(child.value.trim()) ? [child.value] : [];\n if (child.type !== \"element\") return [];\n\n const nested = readChildren(child.children);\n const attributes = readAttributes(child.attributes);\n\n return [isDefined(nested) ? [child.name, attributes, nested] : [child.name, attributes]];\n });\n}\n\n/**\n * Reads SVGO's parsed document into a drawing, from its outer `svg` element.\n *\n * @param tree - The parsed document.\n * @returns The drawing, or undefined when the document has no `svg` element.\n */\nfunction readSvgElement(tree: XastRoot) {\n const element = tree.children.find((child): child is XastElement => child.type === \"element\" && child.name === \"svg\");\n if (!isDefined(element)) return undefined;\n\n // A size like `24px` means 24 units, the way browsers read it.\n const width = element.attributes[\"width\"]?.replace(/px$/u, \"\") ?? \"24\";\n const height = element.attributes[\"height\"]?.replace(/px$/u, \"\") ?? width;\n const attributes = readAttributes(element.attributes, rootOnlyAttributes);\n\n return {\n root: { ...attributes, viewBox: attributes[\"viewBox\"] ?? `0 0 ${width} ${height}` },\n node: readChildren(element.children).filter((child): child is IconElement => typeof child !== \"string\"),\n };\n}\n\n/**\n * Cleans and minifies an icon with SVGO, then reads the result into a drawing. Paths, numbers, and transforms are kept\n * exactly as drawn, since rounding or merging them changes how some icons look, and every identifier gets a prefix\n * unique to the icon, so two icons on one page can't clash.\n *\n * @param svg - The icon's SVG markup.\n * @returns The drawing, or undefined when the markup has no SVG.\n * @throws When the markup can't be parsed.\n */\nfunction readDrawing(svg: string) {\n const result: { drawing?: IconDrawing } = {};\n\n // Browsers accept `xlink:` attributes without the namespace declaration, which React leaves out, but SVGO doesn't.\n const declared =\n svg.includes(\"xlink:\") && !svg.includes(\"xmlns:xlink\")\n ? svg.replace(\"<svg\", '<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\"')\n : svg;\n\n optimize(declared, {\n multipass: true,\n plugins: [\n { name: \"closeOpenUrls\", fn: () => ({ element: { enter: closeOpenUrls } }) },\n {\n name: \"preset-default\",\n params: {\n overrides: {\n cleanupNumericValues: false,\n convertPathData: false,\n convertTransform: false,\n inlineStyles: { onlyMatchedOnce: false },\n mergePaths: false,\n },\n },\n },\n \"removeScripts\",\n \"removeTitle\",\n { name: \"prefixIds\", params: { prefix: `i${createHash(\"sha256\").update(svg).digest(\"hex\").slice(0, 8)}` } },\n {\n name: \"read\",\n fn: () => ({\n root: {\n enter(tree) {\n result.drawing = readSvgElement(tree);\n },\n },\n }),\n },\n ],\n });\n\n return result.drawing;\n}\n\n/**\n * Reads an icon's markup into a drawing, or says why it can't be read.\n *\n * @param svg - The icon's SVG markup.\n * @returns The drawing, or why there isn't one.\n */\nfunction parseDrawing(svg: string) {\n try {\n return readDrawing(svg) ?? \"has no SVG\";\n } catch {\n return \"isn't valid SVG\";\n }\n}\n\n/**\n * Converts one icon into a stored drawing, the same way whichever library it came from.\n *\n * @param source - The icon as read from its library.\n * @returns The converted icon, or why it couldn't be converted.\n */\nexport function convertIcon(source: SourceIcon): ConvertedIcon {\n const drawing = parseDrawing(source.svg);\n if (typeof drawing === \"string\") return { problem: drawing };\n\n const problem = findDrawingProblem(drawing);\n if (isDefined(problem)) return { problem };\n\n const nameWords = new Set(source.name.split(\"-\"));\n const keywords = [...new Set(source.keywords.map((keyword) => keyword.trim().toLowerCase()))].filter(\n (keyword) => isDefined(keyword) && !nameWords.has(keyword),\n );\n\n return { icon: { name: source.name, keywords, node: drawing.node, root: drawing.root } };\n}\n","import { readFile, readdir } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nimport { isDefined, isRecord } from \"@repo/lib/utils\";\nimport type { ElementType, createElement } from \"react\";\nimport type { renderToStaticMarkup } from \"react-dom/server\";\n\nimport type { SourceIcon } from \"@/build/convert\";\nimport { toReactName } from \"@/build/convert\";\n\n/** Root of a 24-unit stroke icon with rounded ends, shared by Lucide and Tabler's outline style. */\nexport const roundStrokeRoot = {\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n \"stroke-width\": \"2\",\n \"stroke-linecap\": \"round\",\n \"stroke-linejoin\": \"round\",\n};\n\n/**\n * Converts a PascalCase export name to the kebab-case name libraries use on their websites, splitting before numbers\n * too, so `Home01` becomes `home-01`.\n *\n * @param name - The export name.\n * @returns The kebab-case name.\n */\nexport function toKebabName(name: string) {\n return name\n .replaceAll(/(?<upper>[A-Z])(?<next>[A-Z][a-z])/gu, \"$<upper>-$<next>\")\n .replaceAll(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, \"$<lower>-$<upper>\")\n .replaceAll(/(?<letter>[a-zA-Z])(?<digit>[0-9])/gu, \"$<letter>-$<digit>\")\n .toLowerCase();\n}\n\n/**\n * Checks whether a module is React, with its element factory.\n *\n * @param value - The module.\n * @returns True if the module is React.\n */\nfunction isReact(value: unknown): value is { createElement: typeof createElement } {\n return isRecord(value) && typeof value[\"createElement\"] === \"function\";\n}\n\n/**\n * Checks whether a module is React's server renderer.\n *\n * @param value - The module.\n * @returns True if the module is the server renderer.\n */\nfunction isServerRenderer(value: unknown): value is { renderToStaticMarkup: typeof renderToStaticMarkup } {\n return isRecord(value) && typeof value[\"renderToStaticMarkup\"] === \"function\";\n}\n\n/**\n * Checks whether a value can be rendered as a React element: a tag name, a component, or a wrapped component such as\n * one made by `memo`.\n *\n * @param value - The value.\n * @returns True if the value is an element type.\n */\nexport function isElementType(value: unknown): value is ElementType {\n return typeof value === \"string\" || typeof value === \"function\" || isRecord(value);\n}\n\n/**\n * Loads the project's React and its server renderer, so markup is written the way the project itself would write it.\n *\n * @param root - The project folder.\n * @returns React's element factory and a function that renders an element to markup, or undefined when the project\n * has no React.\n */\nexport function loadRenderer(root: string) {\n const react = requireFromProject(root, \"react\");\n const server = requireFromProject(root, \"react-dom/server\");\n if (!isReact(react) || !isServerRenderer(server)) return undefined;\n\n return {\n createElement: react.createElement,\n render: (type: ElementType, props: Record<string, unknown> = {}) =>\n server.renderToStaticMarkup(react.createElement(type, props)),\n };\n}\n\n/**\n * Converts attributes to React props, so React writes each name the way SVG spells it.\n *\n * @param attributes - The attributes, in SVG or React naming.\n * @returns The props.\n */\nfunction toProps(attributes: Record<string, unknown>) {\n return Object.fromEntries(\n Object.entries(attributes).flatMap(([name, value]) => (name === \"key\" ? [] : [[toReactName(name), String(value)]])),\n );\n}\n\n/**\n * Writes a list of `[element, attributes]` pairs, the format several libraries ship, as SVG markup. React writes the\n * attributes, so names in either SVG or React form come out right.\n *\n * @param root - The project folder.\n * @param attributes - Attributes of the SVG around the elements.\n * @param value - The list.\n * @returns The markup, or undefined when the value isn't a list of pairs.\n */\nexport function writeElementPairs(root: string, attributes: Record<string, string>, value: unknown) {\n const renderer = loadRenderer(root);\n if (!isDefined(renderer) || !Array.isArray(value)) return undefined;\n\n const { createElement: create, render } = renderer;\n const elements = value.flatMap((pair: unknown, index) =>\n Array.isArray(pair) && typeof pair[0] === \"string\" && isRecord(pair[1])\n ? [create(pair[0], { ...toProps(pair[1]), key: String(index) })]\n : [],\n );\n if (elements.length !== value.length) return undefined;\n\n return render(\"svg\", { xmlns: \"http://www.w3.org/2000/svg\", ...toProps(attributes), children: elements });\n}\n\n/**\n * Reads SVG files from a folder into icons.\n *\n * @param folder - The folder.\n * @param files - The file names to read.\n * @param describe - Gives each file's icon name and keywords.\n * @returns The icons, in the order given.\n */\nexport async function readSvgIcons(\n folder: string,\n files: string[],\n describe: (file: string) => { name: string; keywords: string[] },\n) {\n const icons = await Promise.all(\n files.map(async (file): Promise<SourceIcon> => ({\n ...describe(file),\n svg: await readFile(path.join(folder, file), \"utf8\"),\n })),\n );\n\n return icons;\n}\n\n/**\n * Lists the SVG files in a folder.\n *\n * @param directory - The folder.\n * @returns The file names, sorted.\n */\nexport async function listSvgFiles(directory: string) {\n const files = await readdir(directory);\n\n return files.filter((file) => file.endsWith(\".svg\")).toSorted();\n}\n\n/**\n * Imports a JavaScript module from inside an installed package, by path, since some packages don't allow importing\n * the file by name.\n *\n * @param directory - The package folder.\n * @param file - The module's path within the package.\n * @returns The module's exports.\n */\nexport async function importPackageFile(directory: string, file: string): Promise<Record<string, unknown>> {\n const loaded: unknown = await import(pathToFileURL(path.join(directory, file)).href);\n\n return isRecord(loaded) ? loaded : {};\n}\n\n/**\n * Loads a package the way the project itself resolves it, so rendering uses the project's own copy of React.\n *\n * @param root - The project folder.\n * @param name - The package name.\n * @returns The package's exports.\n */\nexport function requireFromProject(root: string, name: string): unknown {\n return createRequire(path.join(root, \"package.json\"))(name);\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile, readdir } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport { isDefined, isRecord } from \"@repo/lib/utils\";\n\n/** An installed package's folder and version. */\nexport interface InstalledPackage {\n /** Name the package was published under, which differs from the name it's installed under when it's an alias. */\n name: string;\n /** Folder the package is installed in. */\n directory: string;\n /** Version installed. */\n version: string;\n}\n\n/**\n * Lists the plugin's own published code files.\n *\n * @returns The files' paths, sorted.\n */\nexport async function listPluginFiles() {\n const files = await readdir(import.meta.dirname);\n\n return files\n .filter((file) => file.endsWith(\".js\"))\n .toSorted()\n .map((file) => path.join(import.meta.dirname, file));\n}\n\n/**\n * Hashes the plugin's own published code, so anything built from an older version is replaced. It uses the contents\n * rather than modification times, because packages installed from npm all carry the same fixed date.\n *\n * @returns The hash.\n */\nexport async function readPluginBuild() {\n const files = await listPluginFiles();\n const contents = await Promise.all(files.map(async (file) => ({ file, content: await readFile(file) })));\n const hash = createHash(\"sha256\");\n\n for (const { file, content } of contents) hash.update(path.basename(file)).update(content);\n\n return hash.digest(\"hex\").slice(0, 16);\n}\n\n/**\n * Reads and parses a JSON file.\n *\n * @param file - Path to the file.\n * @returns The parsed contents, or undefined when the file is missing or isn't JSON.\n */\nexport async function readJson(file: string): Promise<unknown> {\n try {\n return JSON.parse(await readFile(file, \"utf8\"));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Lists a folder and every folder above it, nearest first.\n *\n * @param directory - The folder to start from.\n * @returns The folders.\n */\nfunction listAncestors(directory: string): string[] {\n const parent = path.dirname(directory);\n\n return parent === directory ? [directory] : [directory, ...listAncestors(parent)];\n}\n\n/**\n * Finds an installed package by walking up from the project folder through each `node_modules`, the way Node does.\n * Its `package.json` is read directly, because some icon packages don't allow importing it.\n *\n * @param root - The project folder.\n * @param name - The package name.\n * @returns The package, or undefined when it isn't installed.\n */\nexport async function findPackage(root: string, name: string): Promise<InstalledPackage | undefined> {\n const candidates = await Promise.all(\n listAncestors(path.resolve(root)).map(async (folder) => {\n const directory = path.join(folder, \"node_modules\", name);\n\n return { directory, manifest: await readJson(path.join(directory, \"package.json\")) };\n }),\n );\n\n for (const { directory, manifest } of candidates) {\n if (isRecord(manifest) && typeof manifest[\"version\"] === \"string\") {\n const published = typeof manifest[\"name\"] === \"string\" ? manifest[\"name\"] : name;\n\n return { name: published, directory, version: manifest[\"version\"] };\n }\n }\n\n return undefined;\n}\n\n/**\n * Lists the packages a project declares, from its dependencies, dev dependencies, and peer dependencies.\n *\n * @param root - The project folder.\n * @returns The declared package names.\n */\nexport async function readDeclaredPackages(root: string) {\n const manifest = await readJson(path.join(root, \"package.json\"));\n if (!isRecord(manifest)) return new Set<string>();\n\n const groups = [manifest[\"dependencies\"], manifest[\"devDependencies\"], manifest[\"peerDependencies\"]];\n\n return new Set(\n groups.flatMap((group) => (isRecord(group) ? Object.keys(group) : [])).filter((name) => isDefined(name)),\n );\n}\n","import path from \"node:path\";\n\nimport { convertCase, isRecord } from \"@repo/lib/utils\";\n\nimport { listSvgFiles, readSvgIcons } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { readJson } from \"@/build/packages\";\n\n/**\n * Creates an adapter for a folder of the project's own SVG files. Each file becomes an icon named after the file, and an\n * optional `keywords.json` in the folder lists each icon's keywords by name.\n *\n * @param library - Identifier of the set.\n * @param folder - The folder, relative to the project.\n * @returns The adapter.\n */\nexport function createCustomAdapter(library: string, folder: string): IconAdapter {\n return {\n library,\n label: convertCase(library, \"title\"),\n packageName: undefined,\n styles: [\"default\"],\n async read({ root }) {\n const directory = path.resolve(root, folder);\n const [files, keywords] = await Promise.all([\n listSvgFiles(directory),\n readJson(path.join(directory, \"keywords.json\")),\n ]);\n\n return readSvgIcons(directory, files, (file) => {\n const name = convertCase(file.slice(0, -\".svg\".length), \"kebab\");\n const listed = isRecord(keywords) ? keywords[name] : undefined;\n\n return { name, keywords: Array.isArray(listed) ? listed.map(String) : [] };\n });\n },\n };\n}\n","import path from \"node:path\";\n\nimport { isDefined, isRecord } from \"@repo/lib/utils\";\n\nimport { importPackageFile, isElementType, loadRenderer, toKebabName } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { readJson } from \"@/build/packages\";\n\n/**\n * Central, read by rendering the React components of its licensed style packages. Each installed\n * `@central-icons-react/` package is a style, named after the rest of its name, so several can be used at once. Each\n * icon is drawn in Central's raw mode, since its default mode draws through a mask.\n */\nexport const centralAdapter: IconAdapter = {\n library: \"central\",\n label: \"Central Icon System\",\n packageName: undefined,\n packagePrefix: \"@central-icons-react/\",\n packageExample: \"@central-icons-react/round-outlined-radius-2-stroke-1.5\",\n styles: [],\n async read({ directory, root }) {\n const renderer = loadRenderer(root);\n if (!isDefined(renderer)) return [];\n\n const [exports, index] = await Promise.all([\n importPackageFile(directory, \"index.mjs\"),\n readJson(path.join(directory, \"icons-index.json\")),\n ]);\n const aliases = isRecord(index) && isRecord(index[\"iconAliases\"]) ? index[\"iconAliases\"] : {};\n\n return Object.entries(exports).flatMap(([exportName, component]) => {\n // Central's components are wrapped in `memo` and `forwardRef`, so they're objects rather than functions.\n if (!exportName.startsWith(\"Icon\") || exportName.endsWith(\"Default\") || !isElementType(component)) return [];\n\n const svg = renderer.render(component, { mode: \"raw\" });\n\n const listed = aliases[exportName];\n const keywords = typeof listed === \"string\" ? listed.split(\",\").map((keyword) => keyword.trim()) : [];\n\n return [{ name: toKebabName(exportName.slice(\"Icon\".length)), keywords, svg }];\n });\n },\n};\n","/** Fills Central Icon System draws each style in. */\nconst centralFills = [\"outlined\", \"filled\"] as const;\n\n/** Corner radii Central Icon System's round styles come in. */\nconst centralRadii = [\"0\", \"1\", \"2\", \"3\"] as const;\n\n/** Stroke widths Central Icon System's styles come in. */\nconst centralStrokes = [\"1\", \"1.5\", \"2\"] as const;\n\n/** Styles Central Icon System publishes, one package each, named after the corners, fill, radius, and stroke. */\nconst centralStyles = [\n ...centralFills.flatMap((fill) =>\n centralRadii.flatMap((radius) =>\n centralStrokes.map((stroke) => `round-${fill}-radius-${radius}-stroke-${stroke}` as const),\n ),\n ),\n ...centralFills.flatMap((fill) =>\n centralStrokes.map((stroke) => `square-${fill}-radius-0-stroke-${stroke}` as const),\n ),\n];\n\n/** Packages Nucleo publishes, each a style named after the rest of its package name. */\nconst nucleoStyles = [\n \"arcade\",\n \"core-essential-fill-24\",\n \"core-essential-fill-32\",\n \"core-essential-fill-48\",\n \"core-essential-outline-24\",\n \"core-essential-outline-32\",\n \"core-essential-outline-48\",\n \"core-fill-24\",\n \"core-fill-32\",\n \"core-fill-48\",\n \"core-outline-24\",\n \"core-outline-32\",\n \"core-outline-48\",\n \"credit-cards\",\n \"flags\",\n \"glass\",\n \"isometric\",\n \"micro-bold\",\n \"micro-bold-essential\",\n \"pixel\",\n \"pixel-essential\",\n \"sharp\",\n \"sharp-essential\",\n \"social-media\",\n \"ui-essential-fill-12\",\n \"ui-essential-fill-18\",\n \"ui-essential-fill-duo-18\",\n \"ui-essential-outline-12\",\n \"ui-essential-outline-18\",\n \"ui-essential-outline-duo-18\",\n \"ui-fill-12\",\n \"ui-fill-18\",\n \"ui-fill-duo-18\",\n \"ui-outline-12\",\n \"ui-outline-18\",\n \"ui-outline-duo-18\",\n] as const;\n\n/**\n * Styles of each library the plugin supports, the first being the default. For a library published as a family of\n * packages, its styles are the packages it publishes, and the installed ones are used.\n */\nexport const iconLibraryStyles = {\n central: centralStyles,\n heroicons: [\"outline\", \"solid\", \"mini\", \"micro\"],\n hugeicons: [\"stroke-rounded\"],\n iconoir: [\"regular\", \"solid\"],\n lucide: [\"default\"],\n nucleo: nucleoStyles,\n phosphor: [\"regular\", \"thin\", \"light\", \"bold\", \"fill\", \"duotone\"],\n tabler: [\"outline\", \"filled\"],\n} as const;\n","import path from \"node:path\";\n\nimport { listSvgFiles, readSvgIcons } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { iconLibraryStyles } from \"@/lib/libraries\";\n\n/** Folder each Heroicons style is published in, named after the size it's drawn for. */\nconst styleFolders: Record<string, string> = {\n outline: \"24/outline\",\n solid: \"24/solid\",\n mini: \"20/solid\",\n micro: \"16/solid\",\n};\n\n/**\n * Heroicons, read from the SVG files the `heroicons` package ships for each style. It has no keywords, so its icons\n * are found by name.\n */\nexport const heroiconsAdapter: IconAdapter = {\n library: \"heroicons\",\n label: \"Heroicons\",\n packageName: \"heroicons\",\n packagePattern: /^(?:heroicons|@heroicons\\/.+)$/u,\n styles: [...iconLibraryStyles.heroicons],\n async read({ directory, style }) {\n const folder = path.join(directory, styleFolders[style] ?? \"24/outline\");\n const files = await listSvgFiles(folder);\n\n return readSvgIcons(folder, files, (file) => ({ name: file.slice(0, -\".svg\".length), keywords: [] }));\n },\n};\n","import { isDefined } from \"@repo/lib/utils\";\n\nimport { importPackageFile, toKebabName, writeElementPairs } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { iconLibraryStyles } from \"@/lib/libraries\";\n\n/** Suffixes Hugeicons adds to its export names, removed to get the icon's own name. */\nconst exportSuffixes = /(?:FreeIcons|Icon)$/u;\n\n/**\n * Hugeicons, read from the shape data `@hugeicons/core-free-icons` exports. It has no keywords, so its icons are found\n * by name. The package also exports many icons under other libraries' names, which aren't used as keywords because\n * they don't describe the icon.\n */\nexport const hugeiconsAdapter: IconAdapter = {\n library: \"hugeicons\",\n label: \"Hugeicons\",\n packageName: \"@hugeicons/core-free-icons\",\n packagePattern: /^@hugeicons\\//u,\n styles: [...iconLibraryStyles.hugeicons],\n async read({ directory, root }) {\n const exports = await importPackageFile(directory, \"dist/esm/index.js\");\n const namesByIcon = new Map<unknown, string[]>();\n\n for (const [exportName, value] of Object.entries(exports)) {\n namesByIcon.set(value, [...(namesByIcon.get(value) ?? []), exportName]);\n }\n\n return [...namesByIcon].flatMap(([value, exportNames]) => {\n const svg = writeElementPairs(root, { viewBox: \"0 0 24 24\", fill: \"none\" }, value);\n const iconNames = exportNames.filter((exportName) => exportName.endsWith(\"Icon\")).toSorted();\n const [primary] = iconNames;\n if (!isDefined(svg) || !isDefined(primary)) return [];\n\n const name = toKebabName(primary.replace(exportSuffixes, \"\"));\n\n return [{ name, keywords: [], svg }];\n });\n },\n};\n","import path from \"node:path\";\n\nimport { listSvgFiles, readSvgIcons } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { iconLibraryStyles } from \"@/lib/libraries\";\n\n/** Iconoir, read from the SVG files the `iconoir` package ships for each style. It has no keywords. */\nexport const iconoirAdapter: IconAdapter = {\n library: \"iconoir\",\n label: \"Iconoir\",\n packageName: \"iconoir\",\n packagePattern: /^iconoir(?:-.+)?$/u,\n styles: [...iconLibraryStyles.iconoir],\n async read({ directory, style }) {\n const folder = path.join(directory, \"icons\", style);\n const files = await listSvgFiles(folder);\n\n return readSvgIcons(folder, files, (file) => ({ name: file.slice(0, -\".svg\".length), keywords: [] }));\n },\n};\n","import path from \"node:path\";\n\nimport { isDefined, isRecord } from \"@repo/lib/utils\";\n\nimport { roundStrokeRoot, writeElementPairs } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { readJson } from \"@/build/packages\";\nimport { iconLibraryStyles } from \"@/lib/libraries\";\n\n/** Lucide, read from the shape data and keywords `lucide-static` ships. */\nexport const lucideAdapter: IconAdapter = {\n library: \"lucide\",\n label: \"Lucide\",\n packageName: \"lucide-static\",\n packagePattern: /^(?:lucide(?:-.+)?|@lucide\\/.+)$/u,\n styles: [...iconLibraryStyles.lucide],\n async read({ directory, root }) {\n const [nodes, tags] = await Promise.all([\n readJson(path.join(directory, \"icon-nodes.json\")),\n readJson(path.join(directory, \"tags.json\")),\n ]);\n if (!isRecord(nodes)) return [];\n\n return Object.entries(nodes).flatMap(([name, value]) => {\n const svg = writeElementPairs(root, roundStrokeRoot, value);\n if (!isDefined(svg)) return [];\n\n const keywords = isRecord(tags) && Array.isArray(tags[name]) ? tags[name].map(String) : [];\n\n return [{ name, keywords, svg }];\n });\n },\n};\n","import { isDefined } from \"@repo/lib/utils\";\n\nimport { importPackageFile, isElementType, loadRenderer, toKebabName } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\n\n/**\n * Finds the style suffix every export name in a Nucleo package ends with, such as `Outline18`, so it can be removed to\n * get each icon's own name.\n *\n * @param names - The export names.\n * @returns The shared suffix, starting at a capital letter, or an empty string when there's none.\n */\nfunction findStyleSuffix(names: string[]) {\n const [first, ...rest] = names;\n if (!isDefined(first)) return \"\";\n\n let length = 0;\n while (length < first.length && rest.every((name) => name.at(-1 - length) === first.at(-1 - length))) length += 1;\n\n const shared = first.slice(first.length - length);\n const start = shared.search(/[A-Z]/u);\n\n return start === -1 ? \"\" : shared.slice(start);\n}\n\n/**\n * Nucleo, read by rendering the React components of its licensed packages. Each installed `nucleo-` package is a\n * style, named after the rest of its name, such as `ui-outline-18`. It has no keywords.\n */\nexport const nucleoAdapter: IconAdapter = {\n library: \"nucleo\",\n label: \"Nucleo\",\n packageName: undefined,\n packagePrefix: \"nucleo-\",\n packageExample: \"nucleo-ui-outline-18\",\n styles: [],\n async read({ directory, root }) {\n const renderer = loadRenderer(root);\n if (!isDefined(renderer)) return [];\n\n const exports = await importPackageFile(directory, \"dist/index.js\");\n const components = Object.entries(exports).flatMap(([exportName, component]) =>\n exportName.startsWith(\"Icon\") && exportName !== \"Icon\" && isElementType(component)\n ? [[exportName, component] as const]\n : [],\n );\n const suffix = findStyleSuffix(components.map(([exportName]) => exportName));\n\n return components.flatMap(([exportName, component]) => {\n const svg = renderer.render(component);\n\n const name = toKebabName(exportName.slice(\"Icon\".length, exportName.length - suffix.length));\n\n return [{ name, keywords: [], svg }];\n });\n },\n};\n","import path from \"node:path\";\n\nimport { isRecord } from \"@repo/lib/utils\";\n\nimport { importPackageFile, listSvgFiles, readSvgIcons } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { iconLibraryStyles } from \"@/lib/libraries\";\n\n/**\n * Reads Phosphor's keywords from the icon list `@phosphor-icons/core` exports.\n *\n * @param directory - The package folder.\n * @returns Keywords keyed by icon name.\n */\nasync function readPhosphorKeywords(directory: string) {\n const { icons } = await importPackageFile(directory, \"dist/index.mjs\");\n if (!Array.isArray(icons)) return new Map<string, string[]>();\n\n return new Map(\n icons.flatMap((icon: unknown) =>\n isRecord(icon) && typeof icon[\"name\"] === \"string\" && Array.isArray(icon[\"tags\"])\n ? [[icon[\"name\"], icon[\"tags\"].map(String)] as const]\n : [],\n ),\n );\n}\n\n/** Phosphor, read from the SVG files `@phosphor-icons/core` ships for each weight. */\nexport const phosphorAdapter: IconAdapter = {\n library: \"phosphor\",\n label: \"Phosphor Icons\",\n packageName: \"@phosphor-icons/core\",\n packagePattern: /^@phosphor-icons\\//u,\n styles: [...iconLibraryStyles.phosphor],\n async read({ directory, style }) {\n const folder = path.join(directory, \"assets\", style);\n const [files, keywords] = await Promise.all([listSvgFiles(folder), readPhosphorKeywords(directory)]);\n const suffix = style === \"regular\" ? \".svg\" : `-${style}.svg`;\n\n return readSvgIcons(\n folder,\n files.filter((file) => file.endsWith(suffix)),\n (file) => {\n const name = file.slice(0, -suffix.length);\n\n return { name, keywords: keywords.get(name) ?? [] };\n },\n );\n },\n};\n","import path from \"node:path\";\n\nimport { isDefined, isRecord } from \"@repo/lib/utils\";\n\nimport { roundStrokeRoot, writeElementPairs } from \"@/build/adapters/shared\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\nimport { readJson } from \"@/build/packages\";\nimport { iconLibraryStyles } from \"@/lib/libraries\";\n\n/** Tabler, read from the shape data and keywords `@tabler/icons` ships for each style. */\nexport const tablerAdapter: IconAdapter = {\n library: \"tabler\",\n label: \"Tabler Icons\",\n packageName: \"@tabler/icons\",\n packagePattern: /^@tabler\\/icons(?:-.+)?$/u,\n styles: [...iconLibraryStyles.tabler],\n async read({ directory, style, root }) {\n const [nodes, details] = await Promise.all([\n readJson(path.join(directory, `tabler-nodes-${style}.json`)),\n readJson(path.join(directory, \"icons.json\")),\n ]);\n if (!isRecord(nodes)) return [];\n\n const attributes = style === \"filled\" ? { viewBox: \"0 0 24 24\", fill: \"currentColor\" } : roundStrokeRoot;\n\n return Object.entries(nodes).flatMap(([name, value]) => {\n const svg = writeElementPairs(root, attributes, value);\n if (!isDefined(svg)) return [];\n\n const detail = isRecord(details) ? details[name] : undefined;\n const tags = isRecord(detail) && Array.isArray(detail[\"tags\"]) ? detail[\"tags\"].map(String) : [];\n\n return [{ name, keywords: tags, svg }];\n });\n },\n};\n","import { centralAdapter } from \"@/build/adapters/central\";\nimport { heroiconsAdapter } from \"@/build/adapters/heroicons\";\nimport { hugeiconsAdapter } from \"@/build/adapters/hugeicons\";\nimport { iconoirAdapter } from \"@/build/adapters/iconoir\";\nimport { lucideAdapter } from \"@/build/adapters/lucide\";\nimport { nucleoAdapter } from \"@/build/adapters/nucleo\";\nimport { phosphorAdapter } from \"@/build/adapters/phosphor\";\nimport { tablerAdapter } from \"@/build/adapters/tabler\";\nimport type { IconAdapter } from \"@/build/adapters/types\";\n\n/** Every library the build step knows how to read from its package. */\nexport const iconAdapters: IconAdapter[] = [\n centralAdapter,\n heroiconsAdapter,\n hugeiconsAdapter,\n iconoirAdapter,\n lucideAdapter,\n nucleoAdapter,\n phosphorAdapter,\n tablerAdapter,\n];\n"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { n as isDefined } from "./utils-COPacfAq.js";
2
+ import { n as iconSvgAttributes } from "./nodes-DAzj56Xn.js";
3
+ import { createElement } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ /**
6
+ * Converts stored attributes to React props, turning a `style` attribute into the object React expects.
7
+ *
8
+ * @param attributes - The stored attributes.
9
+ * @returns The props.
10
+ */
11
+ function toProps({ style, ...attributes }) {
12
+ if (!isDefined(style)) return attributes;
13
+ let declarations = style.split(";").flatMap((declaration) => {
14
+ let [property = "", ...value] = declaration.split(":"), name = property.trim(), joined = value.join(":").trim();
15
+ return !isDefined(name) || !isDefined(joined) ? [] : [[name.startsWith("--") ? name : name.replace(/^-ms-/u, "ms-").replaceAll(/-(?<letter>[a-z])/gu, (_match, letter) => letter.toUpperCase()), joined]];
16
+ });
17
+ return {
18
+ ...attributes,
19
+ style: Object.fromEntries(declarations)
20
+ };
21
+ }
22
+ /**
23
+ * Draws one element of a stored drawing, with its children.
24
+ *
25
+ * @param child - The element, or text inside one.
26
+ * @param index - Its position among its siblings.
27
+ * @returns The element.
28
+ */
29
+ function renderChild(child, index) {
30
+ if (typeof child == "string") return child;
31
+ let [element, attributes, children] = child;
32
+ return createElement(element, {
33
+ ...toProps(attributes),
34
+ key: String(index)
35
+ }, children?.map((nested, position) => renderChild(nested, position)));
36
+ }
37
+ function Drawing({ drawing, ...props }) {
38
+ if (!isDefined(drawing)) return null;
39
+ let root = toProps(drawing.root);
40
+ return /* @__PURE__ */ jsx("svg", {
41
+ ...iconSvgAttributes,
42
+ ...root,
43
+ "aria-hidden": "true",
44
+ ...props,
45
+ children: drawing.node.map((child, index) => renderChild(child, index))
46
+ });
47
+ }
48
+ export { Drawing as t };
49
+
50
+ //# sourceMappingURL=drawing-ByrcBbWB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawing-ByrcBbWB.js","names":["isDefined","ComponentProps","ReactElement","createElement","IconDrawing","IconElement","iconSvgAttributes","toProps","style","attributes","Record","declarations","split","flatMap","declaration","property","value","name","trim","joined","join","key","startsWith","replace","replaceAll","_match","letter","toUpperCase","Object","fromEntries","renderChild","child","index","element","children","String","map","nested","position","DrawingProps","Omit","drawing","Drawing","props","root","node"],"sources":["../src/components/drawing.tsx"],"sourcesContent":["// Consumers render this in server components, where the compiler's memo cache hook can't run.\n\"use no memo\";\n\nimport { isDefined } from \"@repo/lib/utils\";\nimport type { ComponentProps, ReactElement } from \"react\";\nimport { createElement } from \"react\";\n\nimport type { IconDrawing, IconElement } from \"@/lib/nodes\";\nimport { iconSvgAttributes } from \"@/lib/nodes\";\n\n/**\n * Converts stored attributes to React props, turning a `style` attribute into the object React expects.\n *\n * @param attributes - The stored attributes.\n * @returns The props.\n */\nfunction toProps({ style, ...attributes }: Record<string, string>) {\n if (!isDefined(style)) return attributes;\n\n const declarations = style.split(\";\").flatMap((declaration): [string, string][] => {\n const [property = \"\", ...value] = declaration.split(\":\");\n const name = property.trim();\n const joined = value.join(\":\").trim();\n if (!isDefined(name) || !isDefined(joined)) return [];\n\n const key = name.startsWith(\"--\")\n ? name\n : name\n .replace(/^-ms-/u, \"ms-\")\n .replaceAll(/-(?<letter>[a-z])/gu, (_match, letter: string) => letter.toUpperCase());\n\n return [[key, joined]];\n });\n\n return { ...attributes, style: Object.fromEntries(declarations) };\n}\n\n/**\n * Draws one element of a stored drawing, with its children.\n *\n * @param child - The element, or text inside one.\n * @param index - Its position among its siblings.\n * @returns The element.\n */\nfunction renderChild(child: IconElement | string, index: number): ReactElement | string {\n if (typeof child === \"string\") return child;\n\n const [element, attributes, children] = child;\n\n return createElement(\n element,\n { ...toProps(attributes), key: String(index) },\n children?.map((nested, position) => renderChild(nested, position)),\n );\n}\n\nexport type DrawingProps = Omit<ComponentProps<\"svg\">, \"children\"> & { drawing: IconDrawing | undefined };\n\nexport function Drawing({ drawing, ...props }: DrawingProps) {\n if (!isDefined(drawing)) return null;\n\n // Stored roots only hold checked attribute names, but their values are text, not React's literal types.\n const root = toProps(drawing.root) as ComponentProps<\"svg\">;\n\n return (\n <svg {...iconSvgAttributes} {...root} aria-hidden=\"true\" {...props}>\n {drawing.node.map((child, index) => renderChild(child, index))}\n </svg>\n );\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAASO,QAAQ,EAAEC,OAAO,GAAGC,cAAsC;CACjE,IAAI,CAACT,UAAUQ,KAAK,GAAG,OAAOC;CAE9B,IAAME,eAAeH,MAAMI,MAAM,GAAG,CAAC,CAACC,SAASC,gBAAoC;EACjF,IAAM,CAACC,WAAW,IAAI,GAAGC,SAASF,YAAYF,MAAM,GAAG,GACjDK,OAAOF,SAASG,KAAK,GACrBC,SAASH,MAAMI,KAAK,GAAG,CAAC,CAACF,KAAK;EASpC,OARI,CAAClB,UAAUiB,IAAI,KAAK,CAACjB,UAAUmB,MAAM,IAAU,CAAA,IAQ5C,CAAC,CANIF,KAAKK,WAAW,IAAI,IAC5BL,OACAA,KACGM,QAAQ,UAAU,KAAK,CAAC,CACxBC,WAAW,wBAAwBC,QAAQC,WAAmBA,OAAOC,YAAY,CAAC,GAE3ER,MAAM,CAAC;CACvB,CAAC;CAED,OAAO;EAAE,GAAGV;EAAYD,OAAOoB,OAAOC,YAAYlB,YAAY;CAAE;AAClE;;;;;;;;AASA,SAASmB,YAAYC,OAA6BC,OAAsC;CACtF,IAAI,OAAOD,SAAU,UAAU,OAAOA;CAEtC,IAAM,CAACE,SAASxB,YAAYyB,YAAYH;CAExC,OAAO5B,cACL8B,SACA;EAAE,GAAG1B,QAAQE,UAAU;EAAGY,KAAKc,OAAOH,KAAK;CAAE,GAC7CE,UAAUE,KAAKC,QAAQC,aAAaR,YAAYO,QAAQC,QAAQ,CAAC,CACnE;AACF;AAIA,SAAgBI,QAAQ,EAAED,SAAS,GAAGE,SAAuB;CAC3D,IAAI,CAAC3C,UAAUyC,OAAO,GAAG,OAAO;CAGhC,IAAMG,OAAOrC,QAAQkC,QAAQG,IAAI;CAEjC,OACE,oBAAC,OAAD;EAAK,GAAItC;EAAmB,GAAIsC;EAAM,eAAY;EAAO,GAAID;EAC1DF,UAAAA,QAAQI,KAAKT,KAAKL,OAAOC,UAAUF,YAAYC,OAAOC,KAAK,CAAC;CAC1D,CAAA;AAET"}
package/dist/index.d.ts CHANGED
@@ -1,72 +1,124 @@
1
- import { n as iconTypeName, t as SanityIcon } from "./types-_D2jGm25.js";
2
- import { ObjectOptions, TypeAliasDefinition } from "sanity";
1
+ import { n as iconTypeName, t as SanityIcon } from "./types-qlHEYDoN.js";
2
+ import { t as SanityIconBuildOptions } from "./vite-ifICG8y9.js";
3
+ import { BaseSchemaTypeOptions, TypeAliasDefinition } from "sanity";
3
4
  import { ComponentProps } from "react";
4
- import iconNodes from "lucide-static/icon-nodes.json";
5
+ import { SanityIconNames } from "@driftime/sanity-plugin-icon/names";
6
+ /**
7
+ * Styles of each library the plugin supports, the first being the default. For a library published as a family of
8
+ * packages, its styles are the packages it publishes, and the installed ones are used.
9
+ */
10
+ declare const iconLibraryStyles: {
11
+ readonly central: ("round-filled-radius-0-stroke-1" | "round-filled-radius-0-stroke-1.5" | "round-filled-radius-0-stroke-2" | "round-filled-radius-1-stroke-1" | "round-filled-radius-1-stroke-1.5" | "round-filled-radius-1-stroke-2" | "round-filled-radius-2-stroke-1" | "round-filled-radius-2-stroke-1.5" | "round-filled-radius-2-stroke-2" | "round-filled-radius-3-stroke-1" | "round-filled-radius-3-stroke-1.5" | "round-filled-radius-3-stroke-2" | "round-outlined-radius-0-stroke-1" | "round-outlined-radius-0-stroke-1.5" | "round-outlined-radius-0-stroke-2" | "round-outlined-radius-1-stroke-1" | "round-outlined-radius-1-stroke-1.5" | "round-outlined-radius-1-stroke-2" | "round-outlined-radius-2-stroke-1" | "round-outlined-radius-2-stroke-1.5" | "round-outlined-radius-2-stroke-2" | "round-outlined-radius-3-stroke-1" | "round-outlined-radius-3-stroke-1.5" | "round-outlined-radius-3-stroke-2" | "square-filled-radius-0-stroke-1" | "square-filled-radius-0-stroke-1.5" | "square-filled-radius-0-stroke-2" | "square-outlined-radius-0-stroke-1" | "square-outlined-radius-0-stroke-1.5" | "square-outlined-radius-0-stroke-2")[];
12
+ readonly heroicons: readonly ["outline", "solid", "mini", "micro"];
13
+ readonly hugeicons: readonly ["stroke-rounded"];
14
+ readonly iconoir: readonly ["regular", "solid"];
15
+ readonly lucide: readonly ["default"];
16
+ readonly nucleo: readonly ["arcade", "core-essential-fill-24", "core-essential-fill-32", "core-essential-fill-48", "core-essential-outline-24", "core-essential-outline-32", "core-essential-outline-48", "core-fill-24", "core-fill-32", "core-fill-48", "core-outline-24", "core-outline-32", "core-outline-48", "credit-cards", "flags", "glass", "isometric", "micro-bold", "micro-bold-essential", "pixel", "pixel-essential", "sharp", "sharp-essential", "social-media", "ui-essential-fill-12", "ui-essential-fill-18", "ui-essential-fill-duo-18", "ui-essential-outline-12", "ui-essential-outline-18", "ui-essential-outline-duo-18", "ui-fill-12", "ui-fill-18", "ui-fill-duo-18", "ui-outline-12", "ui-outline-18", "ui-outline-duo-18"];
17
+ readonly phosphor: readonly ["regular", "thin", "light", "bold", "fill", "duotone"];
18
+ readonly tabler: readonly ["outline", "filled"];
19
+ };
5
20
  declare module "@sanity/types" {
6
21
  interface IntrinsicDefinitions {
22
+ /** Definition of a field of type `icon`. */
7
23
  icon: SanityIconDefinition;
8
24
  }
9
25
  }
26
+ /** Styles of each supported library, from the plugin's own list. */
27
+ type IconLibraryStyles = typeof iconLibraryStyles;
10
28
  /**
11
- * Names of every icon the library offers, read from the Lucide release a project resolved rather than
12
- * from a list this plugin ships, so an icon added since the last plugin release still completes.
29
+ * Identifier of a library the plugin supports.
13
30
  *
14
31
  * @public
15
32
  */
16
- type SanityIconName = keyof typeof iconNodes;
33
+ type SanityIconLibrary = keyof IconLibraryStyles;
17
34
  /**
18
- * Options an icon field takes, narrowing what its picker offers.
35
+ * Styles a library offers. The project's own icon folders have one style, `default`.
19
36
  *
20
37
  * @public
21
38
  */
22
- interface SanityIconOptions extends ObjectOptions {
23
- /** Icons an author may choose from, offered in the order they are named. Every icon when omitted. */
24
- icons?: SanityIconName[];
25
- }
39
+ type SanityIconStyle<Library extends string> = Library extends SanityIconLibrary ? IconLibraryStyles[Library][number] : "default";
40
+ /**
41
+ * Names of a library's icons, once the build step has listed the installed version's, or any name before then.
42
+ *
43
+ * @public
44
+ */
45
+ type SanityIconName<Library extends string> = Library extends keyof SanityIconNames ? SanityIconNames[Library] : string;
46
+ /** Libraries the build step has listed, or any identifier before it has, so the project's own folders can be named. */
47
+ type ListedLibraryId = [keyof SanityIconNames] extends [never] ? string & NonNullable<unknown> : Extract<keyof SanityIconNames, string>;
48
+ /** Libraries a field can name: the supported ones, plus the project's own folders. */
49
+ type IconLibraryId = SanityIconLibrary | ListedLibraryId;
50
+ /**
51
+ * A choice of library, style, and icons, where the style and icons are checked against the library.
52
+ *
53
+ * @public
54
+ */
55
+ type SanityIconSelection = { [Library in IconLibraryId]: {
56
+ /** Identifier of the icon library, such as `phosphor`. */
57
+ library: Library;
58
+ /** Identifier of the library style, such as `bold`. Defaults to the library's first style. */
59
+ style?: SanityIconStyle<Library>;
60
+ /** Icons authors can choose from, in the order listed. Defaults to every icon. */
61
+ icons?: SanityIconName<Library>[];
62
+ }; }[IconLibraryId];
26
63
  /**
27
- * Shape of a field or array member holding an icon, so its options are completed and checked the way
28
- * a built-in type's are.
64
+ * Options for an icon field. A field that names a library replaces the plugin's library, style, and icons, and one
65
+ * that doesn't uses the plugin's.
66
+ *
67
+ * @public
68
+ */
69
+ type SanityIconOptions = BaseSchemaTypeOptions & (SanityIconSelection | {
70
+ library?: undefined;
71
+ style?: undefined;
72
+ icons?: undefined;
73
+ });
74
+ /**
75
+ * Definition of a field or array member holding an icon, so its options are type-checked like a
76
+ * built-in type's.
29
77
  *
30
78
  * @public
31
79
  */
32
80
  interface SanityIconDefinition extends Omit<TypeAliasDefinition<typeof iconTypeName, undefined>, "options"> {
81
+ /** Options for the field. */
33
82
  options?: SanityIconOptions;
34
83
  }
35
84
  /**
36
- * Everything the plugin accepts, all of which may be left out.
85
+ * Plugin configuration, naming the library every icon field uses unless it names its own.
37
86
  *
38
87
  * @public
39
88
  */
40
- interface SanityIconConfig {
41
- /** Icons an author may choose from, offered in the order they are named. Every icon when omitted. */
42
- icons?: SanityIconName[];
43
- }
89
+ type SanityIconConfig = SanityIconSelection;
44
90
  /**
45
- * Creates the icon field type for Sanity Studio, offering the Lucide library through a searchable
46
- * picker and storing the chosen drawing ready to render.
91
+ * Adds an icon field type to Sanity Studio, with a searchable picker for the installed icon libraries that
92
+ * stores the chosen icon's drawing.
47
93
  *
48
- * @param config - Plugin configuration.
49
- * @returns Sanity plugin definition.
94
+ * @param config - The plugin configuration.
95
+ * @returns The plugin.
50
96
  * @public
51
97
  */
52
- declare function iconPlugin(config?: SanityIconConfig): import("sanity").PluginOptions;
53
- /** Elements an icon's drawing may be built from, narrowed to those that describe a shape. */
54
- declare const iconElements: readonly ["circle", "ellipse", "g", "line", "path", "polygon", "polyline", "rect"];
55
- /** Single shape in an icon's drawing, paired with the attributes it is drawn with. */
56
- type IconElement = [element: (typeof iconElements)[number], attributes: Record<string, string>];
57
- /** An icon's drawing, held as the shapes it is built from rather than as a component. */
98
+ export declare function iconPlugin(config: SanityIconConfig): import("sanity").PluginOptions;
99
+ /** One element in a drawing: its name, its attributes, and any children, which may include text. */
100
+ type IconElement = [element: string, attributes: Record<string, string>, children?: (IconElement | string)[]];
101
+ /** An icon's drawing, stored as a tree of elements rather than a component. */
58
102
  type IconNode = IconElement[];
103
+ /** Attributes for the SVG around a drawing's elements. */
104
+ type IconRoot = Record<string, string>;
105
+ /** An icon's elements together with the SVG attributes they're drawn inside. */
106
+ interface IconDrawing {
107
+ /** Attributes for the SVG around the elements. */
108
+ root: IconRoot;
109
+ /** Elements the icon is drawn from. */
110
+ node: IconNode;
111
+ }
59
112
  type DrawingProps = Omit<ComponentProps<"svg">, "children"> & {
60
- node: IconNode | undefined;
113
+ drawing: IconDrawing | undefined;
61
114
  };
62
115
  /**
63
- * Builds the media a stored icon previews with, so a document lists the drawing an author chose
64
- * rather than one placeholder standing in for every icon alike.
116
+ * Creates preview media for a stored icon, so each document shows its own icon instead of a placeholder.
65
117
  *
66
118
  * @param value - The stored icon.
67
119
  * @returns The media component, or undefined when nothing readable was stored.
68
120
  * @public
69
121
  */
70
- declare function createIconPreview(value: SanityIcon | undefined): (() => import("react").FunctionComponentElement<DrawingProps>) | undefined;
71
- export { type SanityIcon, type SanityIconConfig, type SanityIconDefinition, type SanityIconName, type SanityIconOptions, createIconPreview, iconPlugin };
122
+ export declare function createIconPreview(value: SanityIcon | undefined): (() => import("react").FunctionComponentElement<DrawingProps>) | undefined;
123
+ export type { SanityIconBuildOptions, SanityIconConfig, SanityIconDefinition, SanityIconLibrary, SanityIconName, SanityIconOptions, SanityIconSelection, SanityIconStyle };
72
124
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/plugin.ts","../src/lib/nodes.ts","../src/components/drawing.tsx","../src/lib/preview.ts"],"mappings":";;;;;YAQY;IACR,MAAM;;;;;;;;;KAUE,8BAA8B;;;;;;UAOzB,0BAA0B;;EAEzC,QAAQ;;;;;;;;UASO,6BAA6B,KAAK,2BAA2B;EAC5E,UAAU;;;;;;;UAQK;;EAEf,QAAQ;;;;;;;;;;iBAuBM,WAAW,SAAQ,oCAAqB;;cClElD;;KAGD,eAAe,iBAAiB,uBAAuB,YAAY;;KAG5D,WAAW;KCDX,eAAe,KAAK;EAAuC,MAAM;;;;;;;;;;iBCM7D,kBAAkB,OAAO,gDAAsB,yBAAtB"}
1
+ {"version":3,"file":"index.d.ts","names":["SanityIconNames","BaseSchemaTypeOptions","TypeAliasDefinition","iconLibraryStyles","iconTypeName","_0","SanityIconDefinition","sideEffect","IconLibraryStyles","SanityIconLibrary","SanityIconStyle","Library","SanityIconName","ListedLibraryId","NonNullable","Extract","IconLibraryId","SanityIconSelection","SanityIconOptions","Omit","SanityIconConfig","iconPlugin","IconElement","Record","IconNode","IconRoot","IconDrawing","iconSvgAttributes","findDrawingProblem","root","node","parseIconNode","parseIconRoot","resolveIconDrawing","serializeIconDrawing","ComponentProps","IconDrawing","DrawingProps","Omit","Drawing","drawing","JSX","_$__components_drawing0","SanityIcon","createIconPreview","DrawingProps","_$__components_drawing0.DrawingProps"],"sources":["../src/lib/libraries.ts","../src/plugin.ts","../src/lib/nodes.ts","../src/components/drawing.tsx","../src/lib/preview.ts"],"mappings":";;;;;;;;;cAiEa;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;;YC/DU;;IAER,MAAMM;;;;KAKLE,2BAA2BL;;;;;;KAOpBM,0BAA0BD;;;;;;KAO1BE,gBAAgB,0BAA0BC,gBAAgBF,oBAClED,kBAAkBG;;;;;;KAQVC,eAAe,0BAA0BD,sBAAsBX,kBACvEA,gBAAgBW;;KAIfE,yBAAyBb,4CACjBc,uBACTC,cAAcf;;KAGbgB,gBAAgBP,oBAAoBI;;;;;;KAO7BI,yBACT,WAAWD;;EAEV,SAASL;;EAET,QAAQD,gBAAgBC;;EAExB,QAAQC,eAAeD;KAEzBK;;;;;;;KAQUE,oBAAoBjB,yBAC7BgB;EAAwB;EAAqB;EAAmB;;;;;;;;UAQlDX,6BAA6Ba,KAAKjB,2BAA2BE;;EAE5E,UAAUc;;;;;;;KAQAE,mBAAmBH;;;;;;;;;wBAiBfI,WAAW,QAAQD,oCAAgB;;KC1GvCE,eAAe,iBAAiB,YAAYC,wBAAwB,YAAYD;;KAGhFE,WAAWF;;KAGXG,WAAWF;;UAGNG;;EAEf,MAAMD;;EAEN,MAAMD;;KCuCIa,eAAeC,KAAKH;EAAuC,SAASC;;;;;;;;;wBC1ChEQ,kBAAkB,OAAOD,gDAAsB,yBAAtBD"}