@driftime/sanity-plugin-icon 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Driftime®
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,206 @@
1
+ <div align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-dark.svg" />
4
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-light.svg" />
5
+ <img src="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-light.svg" alt="Icon plugin logo" width="48" />
6
+ </picture>
7
+ <h1>Icon</h1>
8
+ <p><strong>A Sanity Studio plugin by Driftime®</strong></p>
9
+ <p>Lucide icons for Sanity Studio, stored as drawings and rendered without the library.</p>
10
+ </div>
11
+
12
+ <br />
13
+
14
+ ## Overview
15
+
16
+ Icon adds a field type to Sanity Studio that opens the whole Lucide library as a searchable grid. Authors find an icon by its name or by what it depicts, and the drawing itself is stored on the document alongside the name it was chosen by.
17
+
18
+ Rendering costs one component and **under 2 kB gzipped**, with no icon library in your application. That works because the document holds the drawing rather than a reference to it, so nothing needs resolving by name at runtime.
19
+
20
+ <br />
21
+
22
+ <figure>
23
+ <picture>
24
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-selector-dark.png" />
25
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-selector-light.png" />
26
+ <img src="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-selector-light.png" alt="The icon selector open in Sanity Studio, showing a search field above a scrolling grid of the complete Lucide library alongside a count of every icon it offers" />
27
+ </picture>
28
+ <p align="center"><sub><em>Every Lucide icon, searchable from inside the Studio.</em></sub></p>
29
+ </figure>
30
+
31
+ <br />
32
+
33
+ ## Installation
34
+
35
+ Icon is built for Sanity Studio 6 and React 19, and declares both as peer dependencies, so your Studio must already be on those versions. You'll need Node 22.12 or later.
36
+
37
+ ```bash
38
+ bun add -E @driftime/sanity-plugin-icon
39
+ ```
40
+
41
+ <br />
42
+
43
+ ## Basic Setup
44
+
45
+ Add the plugin to your Sanity configuration. It takes no options.
46
+
47
+ ```typescript
48
+ import { defineConfig } from "sanity";
49
+ import { iconPlugin } from "@driftime/sanity-plugin-icon";
50
+ // ...
51
+
52
+ export default defineConfig({
53
+ // ...
54
+ plugins: [iconPlugin()],
55
+ });
56
+ ```
57
+
58
+ That registers an `icon` object type, available alongside Sanity's own. Use it on any document or object.
59
+
60
+ ```typescript
61
+ defineField({
62
+ name: "icon",
63
+ type: "icon",
64
+ description: "Shown beside the heading.",
65
+ });
66
+ ```
67
+
68
+ The type is registered as `icon` and the name is not configurable, so a Studio that already defines its own `icon` type will need to rename that one.
69
+
70
+ <br />
71
+
72
+ ## Picking an Icon
73
+
74
+ - Search matches an icon's name and the terms it is tagged with, so "next" finds `arrow-right`.
75
+ - The complete Lucide set is offered, and the count reflects whatever the current release holds.
76
+ - The last eight icons chosen are remembered, per browser rather than per dataset.
77
+
78
+ <br />
79
+
80
+ <figure>
81
+ <picture>
82
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-search-dark.png" />
83
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-search-light.png" />
84
+ <img src="https://raw.githubusercontent.com/driftime/sanity-plugin-icon/HEAD/.github/assets/icon-search-light.png" alt="The icon selector filtered by the term next, showing thirteen arrow and forward icons matched on what they depict rather than on their names" />
85
+ </picture>
86
+ <p align="center"><sub><em>Searching matches what an icon depicts, so “next” finds every arrow.</em></sub></p>
87
+ </figure>
88
+
89
+ <br />
90
+
91
+ ## Rendering Icons
92
+
93
+ `Icon` is exported from a separate import path that holds no Studio code, so it can be used anywhere outside the Studio, in server and client components alike. It needs no icon library of its own.
94
+
95
+ ```tsx
96
+ import { Icon } from "@driftime/sanity-plugin-icon/render";
97
+
98
+ <Icon value={home.icon} className="size-8" />;
99
+ ```
100
+
101
+ It takes the stored field value directly and renders nothing when that value is absent or unreadable. Props extend `ComponentProps<"svg">`, so `className`, `style`, `aria-label` and the rest pass through to the element.
102
+
103
+ Type the field with `SanityIcon`, available from either import path.
104
+
105
+ ```typescript
106
+ import type { SanityIcon } from "@driftime/sanity-plugin-icon";
107
+
108
+ export interface SanityHome {
109
+ title: string;
110
+ icon?: SanityIcon;
111
+ }
112
+ ```
113
+
114
+ <br />
115
+
116
+ ## Document Previews
117
+
118
+ A document's preview shows the icon its _type_ defines, which is the same glyph for every document of that type. `createIconPreview` builds preview media from the icon an author chose instead.
119
+
120
+ ```typescript
121
+ import { createIconPreview } from "@driftime/sanity-plugin-icon";
122
+
123
+ preview: {
124
+ select: { title: "title", icon: "icon" },
125
+ prepare({ title, icon }) {
126
+ return { title, media: createIconPreview(icon) };
127
+ },
128
+ },
129
+ ```
130
+
131
+ It returns `undefined` when there is nothing to draw, so the preview falls back to Sanity's own placeholder.
132
+
133
+ <br />
134
+
135
+ ## Querying
136
+
137
+ A stored icon needs no special handling in a query. It comes down as a plain object alongside the rest of the document, with nothing to dereference or expand.
138
+
139
+ ```groq
140
+ *[_type == "home"][0] { title, icon }
141
+ ```
142
+
143
+ <br />
144
+
145
+ ## What Gets Stored
146
+
147
+ ```json
148
+ {
149
+ "_type": "icon",
150
+ "name": "house",
151
+ "node": "[[\"path\",{\"d\":\"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\"}], …]"
152
+ }
153
+ ```
154
+
155
+ The `name` records which icon was chosen, and the `node` holds the shapes it is drawn from. Both are written when the icon is picked, which is what lets it render without an icon library.
156
+
157
+ <br />
158
+
159
+ ## Keeping the Icon Set Current
160
+
161
+ The plugin tracks Lucide within its major version, so new icons arrive without waiting for a plugin release. Your lockfile pins whichever version resolved at install, and removing and re-adding the plugin resolves it afresh.
162
+
163
+ ```bash
164
+ bun remove @driftime/sanity-plugin-icon
165
+ bun add -E @driftime/sanity-plugin-icon
166
+ ```
167
+
168
+ `bun update lucide-static` also works, and adds the icon library to your own dependencies so you control the version from then on.
169
+
170
+ <br />
171
+
172
+ ## API
173
+
174
+ | Export | Import from | Purpose |
175
+ | -------------------------- | ------------------------------------- | ------------------------------------------ |
176
+ | `iconPlugin()` | `@driftime/sanity-plugin-icon` | Registers the `icon` type with the Studio. |
177
+ | `createIconPreview(value)` | `@driftime/sanity-plugin-icon` | Builds preview media from a stored icon. |
178
+ | `Icon` | `@driftime/sanity-plugin-icon/render` | Draws a stored icon. |
179
+ | `SanityIcon` | either | Type of the stored value. |
180
+
181
+ <br />
182
+
183
+ ## Acknowledgements
184
+
185
+ Icons come from [Lucide](https://lucide.dev), distributed under the [ISC License](https://github.com/lucide-icons/lucide/blob/main/LICENSE). Icons for controls the Studio already draws come from `@sanity/icons` so they match their surroundings.
186
+
187
+ <br />
188
+ <br />
189
+
190
+ <div align="center">
191
+ <p><strong>Built alongside <a href="https://cairn.driftime.com">Cairn</a>, a starting point for responsible web experiences.</strong></p>
192
+ <p>Part of a suite of Sanity Studio plugins by Driftime®</p>
193
+ <p><a href="https://github.com/driftime/sanity-plugin-handbook">Handbook</a> · <a href="https://github.com/driftime/sanity-plugin-icon">Icon</a></p>
194
+ </div>
195
+
196
+ <br />
197
+
198
+ <div align="center">
199
+ <a href="https://driftime.com">
200
+ <picture>
201
+ <source media="(prefers-color-scheme: dark)" srcset="https://driftime.com/driftime-github-logo-dark.svg" />
202
+ <source media="(prefers-color-scheme: light)" srcset="https://driftime.com/driftime-github-logo.svg" />
203
+ <img src="https://driftime.com/driftime-github-logo.svg" alt="Driftime® Logo" width="100" />
204
+ </picture>
205
+ </a>
206
+ </div>
@@ -0,0 +1,120 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createElement } from "react";
3
+ import { stegaClean } from "@sanity/client/stega";
4
+ /**
5
+ * Checks whether a value is defined and non-empty, treating `false`, empty strings, and objects with
6
+ * no keys as absent. An array is absent unless one of its elements is itself present, while anything
7
+ * built from a class counts as present on existence alone. Not intended for boolean flags.
8
+ *
9
+ * @param value - The value to check.
10
+ * @returns True if the value is defined and not empty.
11
+ */
12
+ function isDefined(value) {
13
+ if (value == null || value === !1) return !1;
14
+ if (typeof value == "string") return value.trim() !== "";
15
+ if (Array.isArray(value)) return value.some((element) => isDefined(element));
16
+ if (typeof value == "object") {
17
+ let prototype = Reflect.getPrototypeOf(value);
18
+ return prototype !== Object.prototype && prototype !== null || Object.keys(value).length > 0;
19
+ }
20
+ return !0;
21
+ }
22
+ /**
23
+ * Converts a string between different casing formats.
24
+ *
25
+ * @param value - The string to convert.
26
+ * @param format - The target casing format.
27
+ * @returns The converted string.
28
+ */
29
+ function convertCase(value, format) {
30
+ let words = value.replaceAll(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, "$<lower> $<upper>").replaceAll(/[-_\s]+/gu, " ").trim().toLowerCase();
31
+ switch (format) {
32
+ case "kebab": return words.replaceAll(/\s+/gu, "-");
33
+ case "snake": return words.replaceAll(/\s+/gu, "_");
34
+ case "camel": return words.replaceAll(/\s+(?<character>.)/gu, (_match, character) => character.toUpperCase());
35
+ case "pascal": return words.replaceAll(/(?:^|\s+)(?<character>.)/gu, (_match, character) => character.toUpperCase());
36
+ case "title": return words.replaceAll(/\b\w/gu, (character) => character.toUpperCase());
37
+ case "sentence": return words.replaceAll(/^(?<character>.)/gu, (character) => character.toUpperCase());
38
+ default: return value;
39
+ }
40
+ }
41
+ /** Elements an icon's drawing may be built from, narrowed to those that describe a shape. */
42
+ const iconElements = [
43
+ "circle",
44
+ "ellipse",
45
+ "g",
46
+ "line",
47
+ "path",
48
+ "polygon",
49
+ "polyline",
50
+ "rect"
51
+ ], iconRootAttributes = {
52
+ xmlns: "http://www.w3.org/2000/svg",
53
+ width: 24,
54
+ height: 24,
55
+ viewBox: "0 0 24 24",
56
+ fill: "none",
57
+ stroke: "currentColor",
58
+ strokeWidth: 2,
59
+ strokeLinecap: "round",
60
+ strokeLinejoin: "round"
61
+ };
62
+ /**
63
+ * Checks whether a parsed value is an icon's drawing, since it arrives as whatever happened to be
64
+ * stored. Shapes are matched against the known elements so nothing else reaches the renderer.
65
+ *
66
+ * @param value - The value to check.
67
+ * @returns True if the value is a drawing.
68
+ */
69
+ function isIconNode(value) {
70
+ return Array.isArray(value) ? value.every((element) => Array.isArray(element) && element.length === 2 && iconElements.some((name) => name === element[0]) && typeof element[1] == "object" && element[1] !== null) : !1;
71
+ }
72
+ /**
73
+ * Reads an icon's drawing from an already-parsed value, for a library handing over its drawings as
74
+ * data rather than as a document field.
75
+ *
76
+ * @param value - The value to read.
77
+ * @returns The drawing, or undefined when the value is not one.
78
+ */
79
+ function parseIconNode(value) {
80
+ return isIconNode(value) ? value : void 0;
81
+ }
82
+ /**
83
+ * Reads an icon's drawing back from the form it is stored in, clearing the stega characters a Sanity
84
+ * fetch leaves behind.
85
+ *
86
+ * @param value - The stored drawing.
87
+ * @returns The drawing, or undefined when nothing readable was stored.
88
+ */
89
+ function resolveIconNode(value) {
90
+ let cleaned = stegaClean(value);
91
+ if (isDefined(cleaned)) try {
92
+ return parseIconNode(JSON.parse(cleaned));
93
+ } catch {
94
+ return;
95
+ }
96
+ }
97
+ /**
98
+ * Writes an icon's drawing into the form it is stored in, so the shapes survive a round trip through
99
+ * a document rather than a component reference that only resolves at build time.
100
+ *
101
+ * @param node - The drawing to store.
102
+ * @returns The drawing ready to store.
103
+ */
104
+ function serialiseIconNode(node) {
105
+ return JSON.stringify(node);
106
+ }
107
+ function Drawing({ node, ...props }) {
108
+ return isDefined(node) ? /* @__PURE__ */ jsx("svg", {
109
+ ...iconRootAttributes,
110
+ "aria-hidden": "true",
111
+ ...props,
112
+ children: node.map(([element, attributes], index) => createElement(element, {
113
+ ...attributes,
114
+ key: String(index)
115
+ }))
116
+ }) : null;
117
+ }
118
+ export { convertCase as a, serialiseIconNode as i, parseIconNode as n, isDefined as o, resolveIconNode as r, Drawing as t };
119
+
120
+ //# sourceMappingURL=drawing-Bo0HTICv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drawing-Bo0HTICv.js","names":["Nullable","isDefined","value","T","undefined","trim","Array","isArray","some","element","prototype","Reflect","getPrototypeOf","Object","keys","length","convertCase","format","words","replaceAll","toLowerCase","_match","character","toUpperCase","stegaClean","isDefined","iconElements","const","IconElement","element","attributes","Record","IconNode","iconRootAttributes","xmlns","width","height","viewBox","fill","stroke","strokeWidth","strokeLinecap","strokeLinejoin","isIconNode","value","Array","isArray","every","length","some","name","parseIconNode","undefined","resolveIconNode","cleaned","parsed","JSON","parse","serialiseIconNode","node","stringify","ComponentProps","createElement","IconNode","iconRootAttributes","isDefined","DrawingProps","Omit","node","Drawing","props","map","element","attributes","index","key","String"],"sources":["../src/lib/utils.ts","../src/lib/nodes.ts","../src/components/drawing.tsx"],"sourcesContent":["import type { Nullable } from \"@/types\";\n\n/**\n * Checks whether a value is defined and non-empty, treating `false`, empty strings, and objects with\n * no keys as absent. An array is absent unless one of its elements is itself present, while anything\n * built from a class counts as present on existence alone. Not intended for boolean flags.\n *\n * @param value - The value to check.\n * @returns True if the value is defined and not empty.\n */\nexport function isDefined<T>(value: Nullable<T> | false): value is T {\n if (value === undefined || value === null || value === false) return false;\n if (typeof value === \"string\") return value.trim() !== \"\";\n if (Array.isArray(value)) return value.some((element) => isDefined(element));\n\n if (typeof value === \"object\") {\n const prototype = Reflect.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return true;\n\n return Object.keys(value).length > 0;\n }\n\n return true;\n}\n\n/**\n * Converts a string between different casing formats.\n *\n * @param value - The string to convert.\n * @param format - The target casing format.\n * @returns The converted string.\n */\nexport function convertCase(value: string, format: \"kebab\" | \"snake\" | \"camel\" | \"pascal\" | \"title\" | \"sentence\") {\n const words = value\n .replaceAll(/(?<lower>[a-z0-9])(?<upper>[A-Z])/gu, \"$<lower> $<upper>\")\n .replaceAll(/[-_\\s]+/gu, \" \")\n .trim()\n .toLowerCase();\n\n switch (format) {\n case \"kebab\": {\n return words.replaceAll(/\\s+/gu, \"-\");\n }\n case \"snake\": {\n return words.replaceAll(/\\s+/gu, \"_\");\n }\n case \"camel\": {\n return words.replaceAll(/\\s+(?<character>.)/gu, (_match, character: string) => character.toUpperCase());\n }\n case \"pascal\": {\n return words.replaceAll(/(?:^|\\s+)(?<character>.)/gu, (_match, character: string) => character.toUpperCase());\n }\n case \"title\": {\n return words.replaceAll(/\\b\\w/gu, (character) => character.toUpperCase());\n }\n case \"sentence\": {\n return words.replaceAll(/^(?<character>.)/gu, (character) => character.toUpperCase());\n }\n default: {\n return value;\n }\n }\n}\n","import { stegaClean } from \"@sanity/client/stega\";\n\nimport { isDefined } from \"@/lib/utils\";\n\n/** Elements an icon's drawing may be built from, narrowed to those that describe a shape. */\nconst iconElements = [\"circle\", \"ellipse\", \"g\", \"line\", \"path\", \"polygon\", \"polyline\", \"rect\"] as const;\n\n/** Single shape in an icon's drawing, paired with the attributes it is drawn with. */\ntype IconElement = [element: (typeof iconElements)[number], attributes: Record<string, string>];\n\n/** An icon's drawing, held as the shapes it is built from rather than as a component. */\nexport type IconNode = IconElement[];\n\n/**\n * Attributes given to the SVG an icon's shapes are drawn inside, mirroring the grid and stroke Lucide\n * draws on. A library working to different conventions would need its own frame, which is why a\n * stored icon carries only what sits inside this one.\n */\nexport const iconRootAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\",\n} as const;\n\n/**\n * Checks whether a parsed value is an icon's drawing, since it arrives as whatever happened to be\n * stored. Shapes are matched against the known elements so nothing else reaches the renderer.\n *\n * @param value - The value to check.\n * @returns True if the value is a drawing.\n */\nfunction isIconNode(value: unknown): value is IconNode {\n if (!Array.isArray(value)) return false;\n\n return value.every(\n (element: unknown) =>\n Array.isArray(element) &&\n element.length === 2 &&\n iconElements.some((name) => name === element[0]) &&\n typeof element[1] === \"object\" &&\n element[1] !== null,\n );\n}\n\n/**\n * Reads an icon's drawing from an already-parsed value, for a library handing over its drawings as\n * data rather than as a document field.\n *\n * @param value - The value to read.\n * @returns The drawing, or undefined when the value is not one.\n */\nexport function parseIconNode(value: unknown) {\n return isIconNode(value) ? value : undefined;\n}\n\n/**\n * Reads an icon's drawing back from the form it is stored in, clearing the stega characters a Sanity\n * fetch leaves behind.\n *\n * @param value - The stored drawing.\n * @returns The drawing, or undefined when nothing readable was stored.\n */\nexport function resolveIconNode(value: string | undefined) {\n const cleaned = stegaClean(value);\n if (!isDefined(cleaned)) return undefined;\n\n try {\n const parsed: unknown = JSON.parse(cleaned);\n\n return parseIconNode(parsed);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Writes an icon's drawing into the form it is stored in, so the shapes survive a round trip through\n * a document rather than a component reference that only resolves at build time.\n *\n * @param node - The drawing to store.\n * @returns The drawing ready to store.\n */\nexport function serialiseIconNode(node: IconNode) {\n return JSON.stringify(node);\n}\n","// Runs inside a consumer's server components, where the compiler's memo cache hook cannot.\n\"use no memo\";\n\nimport type { ComponentProps } from \"react\";\nimport { createElement } from \"react\";\n\nimport type { IconNode } from \"@/lib/nodes\";\nimport { iconRootAttributes } from \"@/lib/nodes\";\nimport { isDefined } from \"@/lib/utils\";\n\nexport type DrawingProps = Omit<ComponentProps<\"svg\">, \"children\"> & { node: IconNode | undefined };\n\nexport function Drawing({ node, ...props }: DrawingProps) {\n if (!isDefined(node)) return null;\n\n return (\n <svg {...iconRootAttributes} aria-hidden=\"true\" {...props}>\n {node.map(([element, attributes], index) => createElement(element, { ...attributes, key: String(index) }))}\n </svg>\n );\n}\n"],"mappings":";;;;;;;;;;;AAUA,SAAgBC,UAAaC,OAAwC;CACnE,IAAIA,SAAiC,QAAQA,UAAU,IAAO,OAAO;CACrE,IAAI,OAAOA,SAAU,UAAU,OAAOA,MAAMG,KAAK,MAAM;CACvD,IAAIC,MAAMC,QAAQL,KAAK,GAAG,OAAOA,MAAMM,MAAMC,YAAYR,UAAUQ,OAAO,CAAC;CAE3E,IAAI,OAAOP,SAAU,UAAU;EAC7B,IAAMQ,YAAYC,QAAQC,eAAeV,KAAK;EAG9C,OAFIQ,cAAcG,OAAOH,aAAaA,cAAc,QAE7CG,OAAOC,KAAKZ,KAAK,CAAC,CAACa,SAAS;CACrC;CAEA,OAAO;AACT;;;;;;;;AASA,SAAgBC,YAAYd,OAAee,QAAuE;CAChH,IAAMC,QAAQhB,MACXiB,WAAW,uCAAuC,mBAAmB,CAAC,CACtEA,WAAW,aAAa,GAAG,CAAC,CAC5Bd,KAAK,CAAC,CACNe,YAAY;CAEf,QAAQH,QAAR;EACE,KAAK,SACH,OAAOC,MAAMC,WAAW,SAAS,GAAG;EAEtC,KAAK,SACH,OAAOD,MAAMC,WAAW,SAAS,GAAG;EAEtC,KAAK,SACH,OAAOD,MAAMC,WAAW,yBAAyBE,QAAQC,cAAsBA,UAAUC,YAAY,CAAC;EAExG,KAAK,UACH,OAAOL,MAAMC,WAAW,+BAA+BE,QAAQC,cAAsBA,UAAUC,YAAY,CAAC;EAE9G,KAAK,SACH,OAAOL,MAAMC,WAAW,WAAWG,cAAcA,UAAUC,YAAY,CAAC;EAE1E,KAAK,YACH,OAAOL,MAAMC,WAAW,uBAAuBG,cAAcA,UAAUC,YAAY,CAAC;EAEtF,SACE,OAAOrB;CAEX;AACF;;ACzDA,MAAMwB,eAAe;CAAC;CAAU;CAAW;CAAK;CAAQ;CAAQ;CAAW;CAAY;AAAM,GAahFO,qBAAqB;CAChCC,OAAO;CACPC,OAAO;CACPC,QAAQ;CACRC,SAAS;CACTC,MAAM;CACNC,QAAQ;CACRC,aAAa;CACbC,eAAe;CACfC,gBAAgB;AAClB;;;;;;;;AASA,SAASC,WAAWC,OAAmC;CAGrD,OAFKC,MAAMC,QAAQF,KAAK,IAEjBA,MAAMG,OACVlB,YACCgB,MAAMC,QAAQjB,OAAO,KACrBA,QAAQmB,WAAW,KACnBtB,aAAauB,MAAMC,SAASA,SAASrB,QAAQ,EAAE,KAC/C,OAAOA,QAAQ,MAAO,YACtBA,QAAQ,OAAO,IACnB,IATkC;AAUpC;;;;;;;;AASA,SAAgBsB,cAAcP,OAAgB;CAC5C,OAAOD,WAAWC,KAAK,IAAIA,QAAQQ,KAAAA;AACrC;;;;;;;;AASA,SAAgBC,gBAAgBT,OAA2B;CACzD,IAAMU,UAAU9B,WAAWoB,KAAK;CAC3BnB,cAAU6B,OAAO,GAEtB,IAAI;EAGF,OAAOH,cAFiBK,KAAKC,MAAMH,OAEdC,CAAM;CAC7B,QAAQ;EACN;CACF;AACF;;;;;;;;AASA,SAAgBG,kBAAkBC,MAAgB;CAChD,OAAOH,KAAKI,UAAUD,IAAI;AAC5B;AC9EA,SAAgBU,QAAQ,EAAED,MAAM,GAAGE,SAAuB;CAGxD,OAFKL,UAAUG,IAAI,IAGjB,oBAAC,OAAD;EAAK,GAAIJ;EAAoB,eAAY;EAAO,GAAIM;EACjDF,UAAAA,KAAKG,KAAK,CAACC,SAASC,aAAaC,UAAUZ,cAAcU,SAAS;GAAE,GAAGC;GAAYE,KAAKC,OAAOF,KAAK;EAAE,CAAC,CAAC;CACtG,CAAA,IALsB;AAO/B"}
@@ -0,0 +1,20 @@
1
+ import { t as SanityIcon } from "./types-nQUVfUHK.js";
2
+ /**
3
+ * Creates the icon field type for Sanity Studio, offering the Lucide library through a searchable
4
+ * picker and storing the chosen drawing ready to render.
5
+ *
6
+ * @returns Sanity plugin definition.
7
+ * @public
8
+ */
9
+ declare const iconPlugin: import("sanity").Plugin<void>;
10
+ /**
11
+ * Builds the media a stored icon previews with, so a document lists the drawing an author chose
12
+ * rather than one placeholder standing in for every icon alike.
13
+ *
14
+ * @param value - The stored icon.
15
+ * @returns The media component, or undefined when nothing readable was stored.
16
+ * @public
17
+ */
18
+ declare function createIconPreview(value: SanityIcon | undefined): (() => import("react").JSX.Element) | undefined;
19
+ export { type SanityIcon, createIconPreview, iconPlugin };
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/plugin.ts","../src/components/preview.tsx"],"mappings":";;;;;;;;cAWa,6BAAU;;;;;;;;;iBCGP,kBAAkB,OAAO,gDAAsB,IAAA"}