@driftime/sanity-plugin-icon 0.4.2 → 0.4.3

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.
package/README.md CHANGED
@@ -380,7 +380,7 @@ When nothing readable is stored, it returns `undefined` and the preview falls ba
380
380
 
381
381
  ## Site
382
382
 
383
- On the site, one component draws a stored icon, and it's imported from `@driftime/sanity-plugin-icon/render`. That path carries no Studio code, so it's safe in server components and anywhere else on the site.
383
+ On the site, `Icon` draws a stored icon, and `getIcon` finds an icon the site chooses itself. Both are imported from `@driftime/sanity-plugin-icon/render`. That path carries no Studio code, so it's safe in server components and anywhere else on the site.
384
384
 
385
385
  <br />
386
386
 
@@ -431,6 +431,41 @@ An icon needs nothing special in a query. It comes back as a plain object with t
431
431
 
432
432
  <br />
433
433
 
434
+ ### Looking Up Icons
435
+
436
+ Some icons are chosen by the site rather than by an author, such as a default for an icon field left empty. `getIcon` finds an icon by name in an installed icon library and returns it as the Studio stores it, so `Icon` draws it the same way as an icon an author chose.
437
+
438
+ ```tsx
439
+ import { getIcon, Icon } from "@driftime/sanity-plugin-icon/render";
440
+ import type { SanityIcon } from "@driftime/sanity-plugin-icon/render";
441
+
442
+ interface FeatureProps {
443
+ icon: SanityIcon | undefined;
444
+ title: string;
445
+ }
446
+
447
+ export async function Feature({ icon, title }: FeatureProps) {
448
+ const value = icon ?? (await getIcon({ library: "lucide", name: "house" }));
449
+
450
+ return (
451
+ <article>
452
+ <Icon value={value} className="size-8" />
453
+ <h3>{title}</h3>
454
+ </article>
455
+ );
456
+ }
457
+ ```
458
+
459
+ | Input | Type | Default | Purpose |
460
+ | --------- | ------------------- | ------------------- | --------------------------------------------------------------------------- |
461
+ | `library` | `SanityIconLibrary` | required | The identifier of the icon library. |
462
+ | `style` | `SanityIconStyle` | the library's first | The style the icon is drawn in. |
463
+ | `name` | `SanityIconName` | required | The icon's name, which completes as it's typed once the build step has run. |
464
+
465
+ It reads the icon libraries the build step converts, so the site's own build needs the build step, as [Adding the Build Step](#adding-the-build-step) describes. It returns `undefined` when the build step hasn't run, or when the icon library, style, or name isn't installed. The first call for a style loads every icon in that style, so it suits server components and images rendered on the server better than the browser.
466
+
467
+ <br />
468
+
434
469
  ## Reference
435
470
 
436
471
  The rest of this document covers the shape of a stored icon and everything the package exports.
@@ -481,6 +516,7 @@ The drawing is written with the name, which is what lets an icon render without
481
516
  | `iconLibraries(options?)` | `@driftime/sanity-plugin-icon/vite` | The build step as a Vite plugin, for a framework's list. |
482
517
  | `withIcons(options?)` | `@driftime/sanity-plugin-icon/next` | Adds the build step to a Next.js configuration. |
483
518
  | `Icon` | `@driftime/sanity-plugin-icon/render` | Draws a stored icon. |
519
+ | `getIcon(lookup)` | `@driftime/sanity-plugin-icon/render` | Finds an icon by name in an installed icon library. |
484
520
 
485
521
  <br />
486
522
 
@@ -503,6 +539,7 @@ The drawing is written with the name, which is what lets an icon render without
503
539
  | `SanityIconWebpackCustomizer` | `@driftime/sanity-plugin-icon/next` | A Next.js `webpack` option the build step runs first. |
504
540
  | `SanityIconProps` | `@driftime/sanity-plugin-icon/render` | Everything `Icon` accepts: an `svg` element's props and `value`. |
505
541
  | `SanityIcon` | `@driftime/sanity-plugin-icon/render` | A stored icon, with its icon library, its name, and its drawing. |
542
+ | `SanityIconLookup` | `@driftime/sanity-plugin-icon/render` | Everything `getIcon` accepts: an icon library, a style, and a name. |
506
543
 
507
544
  <br />
508
545
 
@@ -1,5 +1,3 @@
1
- import { n as isDefined, r as isRecord } from "./utils-COPacfAq.js";
2
- import { i as parseIconRoot, r as parseIconNode } from "./nodes-DAzj56Xn.js";
3
1
  /** Whether this is a development build, the only kind in which the plugin logs. */
4
2
  const isDevelopment = process.env.NODE_ENV === "development", prefixStyle = "color: #2276fc";
5
3
  /**
@@ -50,41 +48,6 @@ function createLogger(name) {
50
48
  }
51
49
  /** Package name, used as the prefix on every logged message. */
52
50
  const pluginName = "@driftime/sanity-plugin-icon", logger = createLogger(pluginName);
53
- /**
54
- * Reads one icon of a converted set, skipping it when its data isn't usable.
55
- *
56
- * @param value - The value to read.
57
- * @returns The icon, or undefined when the value isn't one.
58
- */
59
- function parseIconSetIcon(value) {
60
- if (!isRecord(value)) return;
61
- let { name, keywords, node, root } = value, parsedNode = parseIconNode(node), parsedRoot = isDefined(root) ? parseIconRoot(root) : void 0;
62
- if (typeof name == "string" && Array.isArray(keywords) && isDefined(parsedNode) && (!isDefined(root) || isDefined(parsedRoot))) return {
63
- name,
64
- keywords: keywords.filter((keyword) => typeof keyword == "string"),
65
- node: parsedNode,
66
- ...isDefined(parsedRoot) && { root: parsedRoot }
67
- };
68
- }
69
- /**
70
- * Reads a converted set, keeping only the icons whose data is usable.
71
- *
72
- * @param value - The value to read.
73
- * @returns The set, or undefined when the value isn't one.
74
- */
75
- function parseIconSet(value) {
76
- if (!isRecord(value)) return;
77
- let { library, style, root, icons } = value, parsedRoot = parseIconRoot(root);
78
- if (typeof library == "string" && typeof style == "string" && isDefined(parsedRoot) && Array.isArray(icons)) return {
79
- library,
80
- style,
81
- root: parsedRoot,
82
- icons: icons.flatMap((icon) => {
83
- let parsed = parseIconSetIcon(icon);
84
- return isDefined(parsed) ? [parsed] : [];
85
- })
86
- };
87
- }
88
- export { logger as n, pluginName as r, parseIconSet as t };
51
+ export { pluginName as n, logger as t };
89
52
 
90
- //# sourceMappingURL=sets-kepuObH8.js.map
53
+ //# sourceMappingURL=defaults-BEzCWZtH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults-BEzCWZtH.js","names":["isDevelopment","process","env","isDevelopment","prefixStyle","createLogger","name","prefix","format","message","info","console","warn","error","createLogger","pluginName","logger","\"NODE_ENV\""],"sources":["../../@repo/lib/environment.ts","../../@repo/lib/logger.ts","../src/config/defaults.ts"],"sourcesContent":["/** Whether this is a development build, the only kind in which the plugin logs. */\nexport const isDevelopment = process.env[\"NODE_ENV\"] === \"development\";\n","import { isDevelopment } from \"./environment\";\n\n/** Console style for the prefix, in the blue the Studio uses for its own messages. */\nconst prefixStyle = \"color: #2276fc\";\n\n/**\n * Creates a logger that prefixes messages with the plugin's name and only logs in development builds.\n * Browser consoles show the prefix in blue.\n *\n * @param name - The package name to prefix messages with.\n * @returns Functions that log progress, a warning, or an error, or format a message to throw.\n */\nexport function createLogger(name: string) {\n const prefix = `[${name}]`;\n\n /**\n * Prefixes a message with the package name.\n *\n * @param message - The message.\n * @returns The prefixed message.\n */\n function format(message: string) {\n return `${prefix} ${message}`;\n }\n\n return {\n /**\n * Logs progress worth seeing, such as what a build step did, in development builds only.\n *\n * @param message - What happened.\n */\n info(message: string) {\n if (isDevelopment) console.info(`%c${prefix}%c ${message}`, prefixStyle, \"\");\n },\n /**\n * Logs a warning about something the plugin recovered from, in development builds only.\n *\n * @param message - What happened and what to do about it.\n */\n warn(message: string) {\n if (isDevelopment) console.warn(`%c${prefix}%c ${message}`, prefixStyle, \"\");\n },\n /**\n * Logs an error the plugin couldn't recover from, in development builds only.\n *\n * @param message - What went wrong and what to do about it.\n */\n error(message: string) {\n if (isDevelopment) console.error(`%c${prefix}%c ${message}`, prefixStyle, \"\");\n },\n format,\n };\n}\n","import { createLogger } from \"@repo/lib/logger\";\n\n/** Package name, used as the prefix on every logged message. */\nexport const pluginName = \"@driftime/sanity-plugin-icon\";\n\n/** The package's logger. */\nexport const logger = createLogger(pluginName);\n"],"mappings":";AACA,MAAaA,gBAAgBC,QAAQC,IAAIe,aAAgB,eCEnDb,cAAc;;;;;;;;AASpB,SAAgBC,aAAaC,MAAc;CACzC,IAAMC,SAAS,IAAID,KAAI;;;;;;;CAQvB,SAASE,OAAOC,SAAiB;EAC/B,OAAO,GAAGF,OAAM,GAAIE;CACtB;CAEA,OAAO;;;;;;EAMLC,KAAKD,SAAiB;GACpB,AAAIN,iBAAeQ,QAAQD,KAAK,KAAKH,OAAM,KAAME,WAAWL,aAAa,EAAE;EAC7E;;;;;;EAMAQ,KAAKH,SAAiB;GACpB,AAAIN,iBAAeQ,QAAQC,KAAK,KAAKL,OAAM,KAAME,WAAWL,aAAa,EAAE;EAC7E;;;;;;EAMAS,MAAMJ,SAAiB;GACrB,AAAIN,iBAAeQ,QAAQE,MAAM,KAAKN,OAAM,KAAME,WAAWL,aAAa,EAAE;EAC9E;EACAI;CACF;AACF;;ACjDA,MAAaO,aAAa,gCAGbC,SAASF,aAAaC,UAAU"}
package/dist/index.d.ts CHANGED
@@ -1,52 +1,13 @@
1
- import { n as iconTypeName, t as SanityIcon } from "./types-qlHEYDoN.js";
1
+ import { a as SanityIconName, i as SanityIconLibrary, n as ListedLibraryId, o as SanityIconStyle, r as SanityIcon, s as iconTypeName, t as IconLibraryId } from "./types-D9GjPlhU.js";
2
2
  import { t as SanityIconBuildOptions } from "./vite-ifICG8y9.js";
3
3
  import { BaseSchemaTypeOptions, InitialValueProperty, TypeAliasDefinition } from "sanity";
4
4
  import { ComponentProps } from "react";
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
- };
20
5
  declare module "@sanity/types" {
21
6
  interface IntrinsicDefinitions {
22
7
  /** Definition of a field of type `icon`. */
23
8
  icon: SanityIconDefinition;
24
9
  }
25
10
  }
26
- /** Styles of each supported library, from the plugin's own list. */
27
- type IconLibraryStyles = typeof iconLibraryStyles;
28
- /**
29
- * Identifier of a library the plugin supports.
30
- *
31
- * @public
32
- */
33
- type SanityIconLibrary = keyof IconLibraryStyles;
34
- /**
35
- * Styles a library offers. The project's own icon folders have one style, `default`.
36
- *
37
- * @public
38
- */
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
11
  /**
51
12
  * A choice of library, style, and icons, where the style and icons are checked against the library.
52
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":["SanityIconNames","BaseSchemaTypeOptions","InitialValueProperty","TypeAliasDefinition","iconLibraryStyles","iconTypeName","_0","SanityIconDefinition","sideEffect","IconLibraryStyles","SanityIconLibrary","SanityIconStyle","Library","SanityIconName","ListedLibraryId","NonNullable","Extract","IconLibraryId","SanityIconSelection","SanityIconOptions","SanityIconInitialValue","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,MAAMO;;;;KAKLE,2BAA2BL;;;;;;KAOpBM,0BAA0BD;;;;;;KAO1BE,gBAAgB,0BAA0BC,gBAAgBF,oBAClED,kBAAkBG;;;;;;KAQVC,eAAe,0BAA0BD,sBAAsBZ,kBACvEA,gBAAgBY;;KAIfE,yBAAyBd,4CACjBe,uBACTC,cAAchB;;KAGbiB,gBAAgBP,oBAAoBI;;;;;;KAO7BI,yBACT,WAAWD;;EAEV,SAASL;;EAET,QAAQD,gBAAgBC;;EAExB,QAAQC,eAAeD;KAEzBK;;;;;;;KAQUE,oBAAoBlB,yBAC7BiB;EAAwB;EAAqB;EAAmB;;;;;;;UAOlDE;;EAEf,MAAMP,eAAeC;;;;;;;;UASNP,6BAA6Bc,KAC5ClB,2BAA2BE;;EAI3B,UAAUc;;EAEV,eAAejB,8BAA8BkB;;;;;;;KAQnCE,mBAAmBJ;;;;;;;;;wBAiBfK,WAAW,QAAQD,oCAAgB;;KCzHvCE,eAAe,iBAAiB,YAAYC,wBAAwB,YAAYD;;KAGhFE,WAAWF;;KAGXG,WAAWF;;UAGNG;;EAEf,MAAMD;;EAEN,MAAMD;;KCuCIa,eAAeC,KAAKH;EAAuC,SAASC;;;;;;;;;wBC1ChEQ,kBAAkB,OAAOD,gDAAsB,yBAAtBD"}
1
+ {"version":3,"file":"index.d.ts","names":["BaseSchemaTypeOptions","InitialValueProperty","TypeAliasDefinition","IconLibraryId","ListedLibraryId","SanityIconName","SanityIconStyle","iconTypeName","_0","SanityIconDefinition","sideEffect","SanityIconSelection","Library","SanityIconOptions","SanityIconInitialValue","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/plugin.ts","../src/lib/nodes.ts","../src/components/drawing.tsx","../src/lib/preview.ts"],"mappings":";;;;;YAQY;;IAER,MAAMS;;;;;;;;KASEE,yBACT,WAAWR;;EAEV,SAASS;;EAET,QAAQN,gBAAgBM;;EAExB,QAAQP,eAAeO;KAEzBT;;;;;;;KAQUU,oBAAoBb,yBAC7BW;EAAwB;EAAqB;EAAmB;;;;;;;UAOlDG;;EAEf,MAAMT,eAAeD;;;;;;;;UASNK,6BAA6BM,KAC5Cb,2BAA2BK;;EAI3B,UAAUM;;EAEV,eAAeZ,8BAA8Ba;;;;;;;KAQnCE,mBAAmBL;;;;;;;;;wBAiBfM,WAAW,QAAQD,oCAAgB;;KCnFvCE,eAAe,iBAAiB,YAAYC,wBAAwB,YAAYD;;KAGhFE,WAAWF;;KAGXG,WAAWF;;UAGNG;;EAEf,MAAMD;;EAEN,MAAMD;;KCuCIa,eAAeC,KAAKH;EAAuC,SAASC;;;;;;;;;wBC1ChEQ,kBAAkB,OAAOD,gDAAsB,yBAAtBD"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { n as logger, r as pluginName, t as parseIconSet } from "./sets-kepuObH8.js";
1
+ import { n as pluginName, t as logger } from "./defaults-BEzCWZtH.js";
2
2
  import { n as isDefined, t as convertCase } from "./utils-COPacfAq.js";
3
3
  import { a as resolveIconDrawing, o as serializeIconDrawing } from "./nodes-DAzj56Xn.js";
4
- import { t as Drawing } from "./drawing-ByrcBbWB.js";
4
+ import { a as splitMatches, i as selectIcons, n as normalizeTerms, o as Drawing, r as requestLibrary, t as iconTypeName } from "./types-v7Qz7ogk.js";
5
5
  import { t as getIconSetKey } from "./registry-BEEpqK3z.js";
6
6
  import { ChangeIndicator, FieldActionsProvider, FieldActionsResolver, FormField, defineField, definePlugin, defineType, getPublishedId, set, setIfMissing, unset, useFormValue } from "sanity";
7
7
  import { c } from "react/compiler-runtime";
@@ -12,7 +12,6 @@ import { Box, Button, Card, Dialog, Flex, Grid, Spinner, Stack, Text, TextInput
12
12
  import { SearchIcon } from "@sanity/icons/Search";
13
13
  import { WarningOutlineIcon } from "@sanity/icons/WarningOutline";
14
14
  import { Popover } from "@sanity/ui/popover";
15
- import { iconRegistry } from "@driftime/sanity-plugin-icon/sets";
16
15
  /**
17
16
  * Checks whether a form node has members, as objects and arrays of objects do.
18
17
  *
@@ -326,142 +325,6 @@ function Recent(t0) {
326
325
  }), $[22] = props, $[23] = t2, $[24] = t4, $[25] = t5) : t5 = $[25], t5;
327
326
  }
328
327
  /**
329
- * Normalises text for search, so hyphenated names and multi-word keywords match the same way.
330
- *
331
- * @param value - The text.
332
- * @returns The normalised text.
333
- */
334
- function normalizeTerms(value) {
335
- return value.toLowerCase().replaceAll(/[\s-]+/gu, " ").trim();
336
- }
337
- /**
338
- * Splits text into the parts a search matches and the parts it doesn't, matching the way search does: ignoring case,
339
- * and treating spaces and hyphens alike.
340
- *
341
- * @param text - The text to split.
342
- * @param query - The normalised search.
343
- * @returns The parts in order, each with where it starts in the text and whether it matches.
344
- */
345
- function splitMatches(text, query) {
346
- if (!isDefined(query)) return [{
347
- text,
348
- start: 0,
349
- match: !1
350
- }];
351
- let pattern = query.split(" ").map((word) => word.replaceAll(/[$()*+.?[\\\]^{|}]/gu, String.raw`\$&`)).join(String.raw`[\s-]+`), parts = text.split(RegExp(`(${pattern})`, "giu"));
352
- return parts.map((part, index) => ({
353
- text: part,
354
- start: parts.slice(0, index).join("").length,
355
- match: index % 2 == 1
356
- }));
357
- }
358
- /**
359
- * Narrows the library to the named icons, in the order given. Unknown names are skipped, so a list keeps working
360
- * across library releases.
361
- *
362
- * @param library - Every icon in the library.
363
- * @param names - The icons to offer, or undefined for all of them.
364
- * @returns The icons to offer.
365
- */
366
- function selectIcons(library, names) {
367
- if (!isDefined(names)) return library;
368
- let byName = new Map(library.map((icon) => [icon.name, icon]));
369
- return [...new Set(names)].flatMap((name) => {
370
- let icon = byName.get(name);
371
- return isDefined(icon) ? [icon] : [];
372
- });
373
- }
374
- /**
375
- * Lists identifiers as inline code, separated by commas.
376
- *
377
- * @param identifiers - The identifiers.
378
- * @returns The list.
379
- */
380
- function formatList(identifiers) {
381
- return identifiers.map((identifier) => `\`${identifier}\``).join(", ");
382
- }
383
- /**
384
- * Describes why a library the project hasn't installed can't be shown, and what to add.
385
- *
386
- * @param label - Readable name of the library.
387
- * @param packageName - Package the library is read from, or an example of one for a family of packages.
388
- * @param family - Whether the library is a family of packages, one per style.
389
- * @param listed - Whether the project's `package.json` lists the package.
390
- * @param sitePackage - Another package of the library the project lists, or undefined when there's none.
391
- * @returns The problem.
392
- */
393
- function describeMissingLibrary(label, packageName, family, listed, sitePackage) {
394
- return listed ? {
395
- title: `${label} isn't installed yet`,
396
- description: `\`${packageName}\` is in \`package.json\` but not in \`node_modules\`. Reinstall the project's dependencies.`
397
- } : isDefined(sitePackage) ? {
398
- title: `${label} needs \`${packageName}\``,
399
- description: `The Studio reads ${label} from \`${packageName}\`, not \`${sitePackage}\`. Add it as a dev dependency.`
400
- } : {
401
- title: `${label} isn't installed`,
402
- description: family ? `Install a ${label} style package, such as \`${packageName}\`.` : `Install \`${packageName}\` in the project.`
403
- };
404
- }
405
- /**
406
- * Loads one library style from the sets the build step converted.
407
- *
408
- * @param library - Identifier of the library, or undefined when none is set.
409
- * @param style - Identifier of the style, or undefined for the library's default.
410
- * @returns The icons, or why they can't be shown.
411
- */
412
- async function readLibrary(library, style) {
413
- if (!isDefined(library)) return { problem: {
414
- title: "No icon library set",
415
- description: "Set `library` in the icon plugin's configuration or in the field's options."
416
- } };
417
- if (!iconRegistry.ready) return { problem: {
418
- title: "Icons aren't set up",
419
- description: "Add `withIcons()` to the Studio's build configuration, then restart the Studio."
420
- } };
421
- let info = iconRegistry.libraries[library];
422
- if (!isDefined(info)) return { problem: {
423
- title: "Unknown icon library",
424
- description: `There's no icon library called \`${library}\`. Use one of: ${formatList(Object.keys(iconRegistry.libraries))}.`
425
- } };
426
- let { label, packageName, packagePrefix, styles, listed, installed, sitePackage } = info;
427
- if (!installed) return { problem: describeMissingLibrary(label, packageName, isDefined(packagePrefix), listed, sitePackage) };
428
- let resolvedStyle = style ?? styles[0] ?? "", loader = iconRegistry.sets[getIconSetKey(library, resolvedStyle)];
429
- if (!isDefined(loader)) return { problem: isDefined(packagePrefix) ? {
430
- title: `${label} style \`${resolvedStyle}\` isn't installed`,
431
- description: `Install \`${packagePrefix}${resolvedStyle}\` in the project.`
432
- } : {
433
- title: `Unknown ${label} style`,
434
- description: `${label} has no \`${resolvedStyle}\` style. Use one of: ${formatList(styles)}.`
435
- } };
436
- let module = await loader(), set = parseIconSet(module.default);
437
- return isDefined(set) ? { icons: set.icons.map(({ name, keywords, node, root }) => ({
438
- name,
439
- label: convertCase(name, "title"),
440
- tags: keywords.join(", "),
441
- drawing: {
442
- root: root ?? set.root,
443
- node
444
- },
445
- terms: normalizeTerms([name, ...keywords].join(" "))
446
- })) } : { problem: {
447
- title: `Couldn't load ${label}`,
448
- description: "Restart the Studio and try again."
449
- } };
450
- }
451
- /** Library requests shared by every field in the session, keyed by library and style, since the data never changes. */
452
- const libraryRequests = /* @__PURE__ */ new Map();
453
- /**
454
- * Loads a library style, reusing a request already in progress.
455
- *
456
- * @param library - Identifier of the library, or undefined when none is set.
457
- * @param style - Identifier of the style, or undefined for the library's default.
458
- * @returns The icons, or why they can't be shown.
459
- */
460
- async function requestLibrary(library, style) {
461
- let key = getIconSetKey(library ?? "", style ?? ""), request = libraryRequests.get(key);
462
- return isDefined(request) || (request = readLibrary(library, style), libraryRequests.set(key, request)), await request;
463
- }
464
- /**
465
328
  * Gap between the tooltip and its cell, set through margins because `@sanity/ui` offers no other way.
466
329
  * Only the top is set, since the tooltip always appears above the cell.
467
330
  */
@@ -938,8 +801,6 @@ function resolveIconOptions(options, config) {
938
801
  icons
939
802
  };
940
803
  }
941
- /** Schema type name of the icon object. */
942
- const iconTypeName = "icon";
943
804
  /**
944
805
  * Creates the patches that store an icon, with the library and style it was chosen from.
945
806
  *