sanity-plugin-iconify 1.1.0 → 1.1.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Wannes Salomé
3
+ Copyright (c) 2024 Wannes Salomé
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/index.cjs ADDED
@@ -0,0 +1,283 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: !0 });
3
+ var jsxRuntime = require("react/jsx-runtime"), sanity = require("sanity"), ui = require("@sanity/ui"), react = require("react"), react$1 = require("@headlessui/react"), tsPattern = require("ts-pattern"), reactQuery = require("@tanstack/react-query"), useDebounce = require("use-debounce"), styled = require("styled-components"), react$2 = require("@iconify/react"), icons = require("@sanity/icons"), utils = require("@iconify/utils"), changeCase = require("change-case");
4
+ function _interopDefaultCompat(e) {
5
+ return e && typeof e == "object" && "default" in e ? e : { default: e };
6
+ }
7
+ var styled__default = /* @__PURE__ */ _interopDefaultCompat(styled);
8
+ const BASE_API_URL = "https://api.iconify.design";
9
+ function fetchJson({ url, signal }) {
10
+ return fetch(url, { signal }).then((response) => {
11
+ if (!response.ok)
12
+ throw new Error(`Network error: status ${response.status}`);
13
+ return response.json();
14
+ }).then(
15
+ (result) => result,
16
+ (error) => {
17
+ throw error instanceof Error ? error : (console.error(`Unknown error: ${error}`), new Error("Something went wrong"));
18
+ }
19
+ );
20
+ }
21
+ function useSearch({ collections }) {
22
+ const queryClient2 = reactQuery.useQueryClient(), [term, setTerm] = react.useState(""), [debouncedTerm, setDebouncedTerm] = useDebounce.useDebounce(term, 500), updateTerm = react.useCallback(
23
+ (newTerm, updateImmediately = !1) => {
24
+ setTerm(newTerm), updateImmediately && setDebouncedTerm(newTerm);
25
+ },
26
+ [setDebouncedTerm]
27
+ ), { isLoading, isError, error, data, isPlaceholderData } = reactQuery.useQuery({
28
+ queryKey: ["search", collections, debouncedTerm],
29
+ queryFn: async ({ signal }) => {
30
+ var _a;
31
+ const url = new URL("/search", BASE_API_URL);
32
+ url.searchParams.append("query", debouncedTerm), url.searchParams.append("limit", "60"), collections && url.searchParams.append("prefixes", collections.join(","));
33
+ const result = debouncedTerm ? await fetchJson({ url, signal }) : null;
34
+ return result && Object.entries(result.collections).forEach(([prefix, info]) => {
35
+ queryClient2.setQueryData(["iconSetInfo", prefix], info);
36
+ }), (_a = result == null ? void 0 : result.icons) != null ? _a : [];
37
+ },
38
+ enabled: debouncedTerm.length > 0,
39
+ placeholderData: reactQuery.keepPreviousData,
40
+ staleTime: 5 * 60 * 1e3
41
+ // 5 minutes
42
+ });
43
+ return {
44
+ term,
45
+ setTerm: updateTerm,
46
+ debouncedTerm,
47
+ isLoading,
48
+ isError,
49
+ error,
50
+ data,
51
+ isPreviousData: isPlaceholderData
52
+ };
53
+ }
54
+ function useIconSetInfo({ prefix }) {
55
+ return reactQuery.useQuery({
56
+ queryKey: ["iconSetInfo", prefix],
57
+ queryFn: async ({ signal }) => {
58
+ var _a;
59
+ if (!prefix)
60
+ return null;
61
+ const url = new URL("/collection", BASE_API_URL);
62
+ url.searchParams.append("prefix", prefix), url.searchParams.append("info", "true");
63
+ const result = await fetchJson({ url, signal });
64
+ return (_a = result == null ? void 0 : result.info) != null ? _a : null;
65
+ },
66
+ staleTime: 1 / 0
67
+ });
68
+ }
69
+ const ComboboxWrapper = styled__default.default(ui.Grid)`
70
+ grid-template-columns: 1fr min-content;
71
+ position: relative;
72
+ `, OptionsWrapper = styled__default.default(ui.Box)`
73
+ box-sizing: border-box;
74
+ padding: 0.5rem;
75
+
76
+ & [role='listbox'] {
77
+ display: grid;
78
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 2.5rem), 1fr));
79
+ gap: 0.5rem;
80
+ list-style: none;
81
+ margin: 0;
82
+ padding: 0;
83
+
84
+ @media (min-width: 650px) {
85
+ grid-template-columns: repeat(10, minmax(min(100%, 2.5rem), 1fr));
86
+ }
87
+ }
88
+
89
+ & [role='option'] {
90
+ display: grid;
91
+ place-items: center;
92
+
93
+ & button {
94
+ aspect-ratio: 1;
95
+ cursor: pointer;
96
+ width: 100%;
97
+
98
+ & > [data-ui='Box'] {
99
+ display: flex;
100
+ }
101
+ }
102
+ }
103
+ `;
104
+ function MessageWrapper({ children }) {
105
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", muted: !0, children }) });
106
+ }
107
+ const SearchInput = react.forwardRef((props, ref) => {
108
+ const { term, selectedIcon, onChange } = props;
109
+ return /* @__PURE__ */ jsxRuntime.jsx(
110
+ react$1.Combobox.Input,
111
+ {
112
+ as: ui.TextInput,
113
+ ref,
114
+ inputMode: "search",
115
+ value: term,
116
+ onChange,
117
+ icon: selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(react$2.Icon, { icon: selectedIcon }) : null,
118
+ placeholder: selectedIcon ? "Search and replace selected icon..." : "Search for an icon..."
119
+ }
120
+ );
121
+ });
122
+ SearchInput.displayName = "SearchInput";
123
+ function SearchResults(props) {
124
+ const { state, data } = props;
125
+ return state === "initial" ? /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Search for icons" }) : state === "loading" ? /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Searching..." }) : state === "error" ? /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Something went wrong..." }) : state === "empty" ? /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "No icons found" }) : /* @__PURE__ */ jsxRuntime.jsx(react$1.Combobox.Options, { style: { opacity: state === "stale" ? 0.5 : 1 }, children: data.map((icon) => /* @__PURE__ */ jsxRuntime.jsx(react$1.Combobox.Option, { value: icon, children: ({ active }) => /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { padding: 3, mode: "bleed", selected: active, children: /* @__PURE__ */ jsxRuntime.jsx(react$2.Icon, { icon, width: "100%", height: "100%" }) }) }, icon)) });
126
+ }
127
+ function UnsetButton(props) {
128
+ const { onUnset } = props;
129
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { border: !0, borderLeft: !1, padding: 1, display: "flex", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.TrashIcon, {}), onClick: onUnset, mode: "bleed", fontSize: 1, padding: 2 }) });
130
+ }
131
+ function IconifyCombobox(props) {
132
+ const { selectedIcon, onSelect: pushSelection, collections } = props, id = react.useId(), toast = ui.useToast(), inputRef = react.useRef(null), { term, setTerm, debouncedTerm, isLoading, isError, error, data, isPreviousData } = useSearch({
133
+ collections
134
+ }), handleTermChange = react.useCallback(
135
+ (event) => setTerm(event.target.value),
136
+ [setTerm]
137
+ ), handleSelect = react.useCallback(
138
+ (icon) => {
139
+ pushSelection(icon), setTerm("", !0);
140
+ },
141
+ [pushSelection, setTerm]
142
+ ), handleUnset = react.useCallback(() => handleSelect(""), [handleSelect]);
143
+ return react.useEffect(() => {
144
+ isError && (console.error("Iconify input error:", error), toast.push({
145
+ id,
146
+ status: "error",
147
+ title: "Iconify input error",
148
+ description: error == null ? void 0 : error.message
149
+ }));
150
+ }, [error, id, isError, toast]), /* @__PURE__ */ jsxRuntime.jsxs(ComboboxWrapper, { children: [
151
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.Combobox, { onChange: handleSelect, children: ({ open }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
152
+ /* @__PURE__ */ jsxRuntime.jsx(
153
+ SearchInput,
154
+ {
155
+ ref: inputRef,
156
+ term,
157
+ selectedIcon,
158
+ onChange: handleTermChange
159
+ }
160
+ ),
161
+ /* @__PURE__ */ jsxRuntime.jsx(
162
+ ui.Popover,
163
+ {
164
+ open,
165
+ placement: "bottom",
166
+ arrow: !1,
167
+ matchReferenceWidth: !0,
168
+ portal: !0,
169
+ constrainSize: !0,
170
+ referenceElement: inputRef.current,
171
+ content: /* @__PURE__ */ jsxRuntime.jsx(OptionsWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(
172
+ SearchResults,
173
+ {
174
+ state: tsPattern.match(!0).returnType().with(isLoading, () => "loading").with(!debouncedTerm, () => "initial").with(isError, () => "error").with(!data || data.length === 0, () => "empty").with(isPreviousData, () => "stale").otherwise(() => "data"),
175
+ data
176
+ }
177
+ ) })
178
+ }
179
+ )
180
+ ] }) }),
181
+ selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(UnsetButton, { onUnset: handleUnset }) : null
182
+ ] });
183
+ }
184
+ const queryClient = new reactQuery.QueryClient();
185
+ function QueryClientProvider(props) {
186
+ return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: props.children });
187
+ }
188
+ function usePrettyIconName(props) {
189
+ var _a, _b;
190
+ const { name } = props, iconMeta = react.useMemo(
191
+ () => {
192
+ var _a2;
193
+ return (_a2 = props.iconMeta) != null ? _a2 : name ? utils.stringToIcon(name) : null;
194
+ },
195
+ [name, props.iconMeta]
196
+ ), iconSetInfo = useIconSetInfo({ prefix: (_a = iconMeta == null ? void 0 : iconMeta.prefix) != null ? _a : null });
197
+ return react.useMemo(
198
+ () => {
199
+ var _a2, _b2;
200
+ return iconMeta ? {
201
+ name: changeCase.sentenceCase(iconMeta.name),
202
+ collection: (_b2 = (_a2 = iconSetInfo.data) == null ? void 0 : _a2.name) != null ? _b2 : iconMeta.prefix
203
+ } : null;
204
+ },
205
+ [iconMeta, (_b = iconSetInfo.data) == null ? void 0 : _b.name]
206
+ );
207
+ }
208
+ function IconifyInput(props) {
209
+ var _a, _b, _c, _d, _e;
210
+ const { config, value, onChange: pushChange, schemaType } = props, selectedIcon = (_a = value == null ? void 0 : value.name) != null ? _a : null, options = schemaType.options, collections = !!((_b = options == null ? void 0 : options.collections) != null && _b.length) && options.collections || !!((_c = config == null ? void 0 : config.collections) != null && _c.length) && config.collections || null, showName = (_e = (_d = options == null ? void 0 : options.showName) != null ? _d : config == null ? void 0 : config.showName) != null ? _e : !1, parentTheme = ui.useTheme(), theme = react.useMemo(
211
+ () => parentTheme ? { ...parentTheme.sanity, color: ui.studioTheme.color } : ui.studioTheme,
212
+ [parentTheme]
213
+ ), handleSelect = react.useCallback(
214
+ (icon) => {
215
+ pushChange(icon === "" ? sanity.unset() : sanity.set(icon, ["name"]));
216
+ },
217
+ [pushChange]
218
+ );
219
+ return /* @__PURE__ */ jsxRuntime.jsx(QueryClientProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
220
+ /* @__PURE__ */ jsxRuntime.jsx(
221
+ IconifyCombobox,
222
+ {
223
+ selectedIcon,
224
+ onSelect: handleSelect,
225
+ collections
226
+ }
227
+ ),
228
+ showName && selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(IconifyNameDisplay, { name: selectedIcon }) : null
229
+ ] }) }) });
230
+ }
231
+ function IconifyNameDisplay(props) {
232
+ var _a;
233
+ const { name } = props, prettyName = usePrettyIconName({ name });
234
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
235
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, muted: !0, children: "Selected:" }),
236
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, weight: "semibold", children: (_a = prettyName == null ? void 0 : prettyName.name) != null ? _a : name }),
237
+ (prettyName == null ? void 0 : prettyName.collection) && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: 1, muted: !0, style: { fontStyle: "italic" }, children: [
238
+ "by ",
239
+ prettyName == null ? void 0 : prettyName.collection
240
+ ] })
241
+ ] });
242
+ }
243
+ function IconifyPreview(props) {
244
+ const { title } = props, iconName = typeof props.title == "string" ? utils.stringToIcon(props.title) : null;
245
+ return typeof title == "string" && iconName ? /* @__PURE__ */ jsxRuntime.jsx(QueryClientProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(IconifyPreviewInner, { ...props, iconName: title, iconMeta: iconName }) }) : props.renderDefault(props);
246
+ }
247
+ function IconifyPreviewInner(props) {
248
+ var _a;
249
+ const { iconMeta, iconName, ...previewProps } = props, prettyName = usePrettyIconName({ iconMeta });
250
+ return props.renderDefault({
251
+ ...previewProps,
252
+ media: /* @__PURE__ */ jsxRuntime.jsx(react$2.Icon, { icon: iconName }),
253
+ title: (_a = prettyName == null ? void 0 : prettyName.name) != null ? _a : iconName,
254
+ subtitle: prettyName == null ? void 0 : prettyName.collection
255
+ });
256
+ }
257
+ const iconify = sanity.definePlugin((config = {}) => ({
258
+ name: "sanity-plugin-iconify",
259
+ schema: {
260
+ types: [
261
+ {
262
+ name: "icon",
263
+ title: "Icon",
264
+ type: "object",
265
+ fields: [
266
+ {
267
+ name: "name",
268
+ title: "Name",
269
+ type: "string"
270
+ }
271
+ ],
272
+ components: {
273
+ input: (props) => /* @__PURE__ */ jsxRuntime.jsx(IconifyInput, { ...props, config }),
274
+ preview: IconifyPreview,
275
+ // This makes sure the input component is not indented
276
+ field: (props) => props.renderDefault({ ...props, level: 0 })
277
+ }
278
+ }
279
+ ]
280
+ }
281
+ }));
282
+ exports.iconify = iconify;
283
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/lib/api.ts","../src/combobox/iconify-combobox.styles.tsx","../src/combobox/search-input.tsx","../src/combobox/search-result.tsx","../src/combobox/unset-button.tsx","../src/combobox/iconify-combobox.tsx","../src/lib/query-client.tsx","../src/lib/use-pretty-icon-name.ts","../src/iconify-input.tsx","../src/iconify-preview.tsx","../src/iconify-plugin.tsx"],"sourcesContent":["import { IconifyInfo } from '@iconify/types';\nimport { keepPreviousData, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useState } from 'react';\nimport { useDebounce } from 'use-debounce';\n\nimport { IconifySearchResult } from './types';\n\nconst BASE_API_URL = 'https://api.iconify.design';\n\nfunction fetchJson<T>({ url, signal }: { url: string | URL; signal?: AbortSignal }): Promise<T> {\n return fetch(url, { signal })\n .then((response) => {\n if (!response.ok) {\n throw new Error(`Network error: status ${response.status}`);\n }\n\n return response.json();\n })\n .then(\n (result) => result as T,\n (error) => {\n if (error instanceof Error) {\n throw error;\n } else {\n console.error(`Unknown error: ${error}`);\n throw new Error('Something went wrong');\n }\n },\n );\n}\n\nexport function useSearch({ collections }: { collections: string[] | null }) {\n const queryClient = useQueryClient();\n const [term, setTerm] = useState('');\n const [debouncedTerm, setDebouncedTerm] = useDebounce(term, 500);\n\n const updateTerm = useCallback(\n (newTerm: string, updateImmediately = false) => {\n setTerm(newTerm);\n\n if (updateImmediately) {\n setDebouncedTerm(newTerm);\n }\n },\n [setDebouncedTerm],\n );\n\n const { isLoading, isError, error, data, isPlaceholderData } = useQuery<string[], Error>({\n queryKey: ['search', collections, debouncedTerm],\n queryFn: async ({ signal }) => {\n const url = new URL(`/search`, BASE_API_URL);\n\n url.searchParams.append('query', debouncedTerm);\n url.searchParams.append('limit', '60');\n\n if (collections) {\n url.searchParams.append('prefixes', collections.join(','));\n }\n\n const result = debouncedTerm ? await fetchJson<IconifySearchResult>({ url, signal }) : null;\n\n if (result) {\n // Cache the info for each collection\n Object.entries(result.collections).forEach(([prefix, info]) => {\n queryClient.setQueryData<IconifyInfo>(['iconSetInfo', prefix], info);\n });\n }\n\n return result?.icons ?? [];\n },\n enabled: debouncedTerm.length > 0,\n placeholderData: keepPreviousData,\n staleTime: 5 * 60 * 1000, // 5 minutes\n });\n\n return {\n term,\n setTerm: updateTerm,\n debouncedTerm,\n isLoading,\n isError,\n error,\n data,\n isPreviousData: isPlaceholderData,\n };\n}\n\nexport function useIconSetInfo({ prefix }: { prefix?: string | null }) {\n return useQuery<IconifyInfo | null, Error>({\n queryKey: ['iconSetInfo', prefix],\n queryFn: async ({ signal }) => {\n if (!prefix) return null;\n\n const url = new URL('/collection', BASE_API_URL);\n\n url.searchParams.append('prefix', prefix);\n url.searchParams.append('info', 'true');\n\n const result = await fetchJson<{ info: IconifyInfo }>({ url, signal });\n\n return result?.info ?? null;\n },\n staleTime: Infinity,\n });\n}\n","import { Box, Card, Grid, Text } from '@sanity/ui';\nimport { ReactNode } from 'react';\nimport styled from 'styled-components';\n\nexport const ComboboxWrapper = styled(Grid)`\n grid-template-columns: 1fr min-content;\n position: relative;\n`;\n\nexport const OptionsWrapper = styled(Box)`\n box-sizing: border-box;\n padding: 0.5rem;\n\n & [role='listbox'] {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(min(100%, 2.5rem), 1fr));\n gap: 0.5rem;\n list-style: none;\n margin: 0;\n padding: 0;\n\n @media (min-width: 650px) {\n grid-template-columns: repeat(10, minmax(min(100%, 2.5rem), 1fr));\n }\n }\n\n & [role='option'] {\n display: grid;\n place-items: center;\n\n & button {\n aspect-ratio: 1;\n cursor: pointer;\n width: 100%;\n\n & > [data-ui='Box'] {\n display: flex;\n }\n }\n }\n`;\n\nexport function MessageWrapper({ children }: { children: ReactNode }) {\n return (\n <Card padding={4}>\n <Text align=\"center\" muted>\n {children}\n </Text>\n </Card>\n );\n}\n","import { Combobox } from '@headlessui/react';\nimport { Icon } from '@iconify/react';\nimport { TextInput } from '@sanity/ui';\nimport { ChangeEventHandler, forwardRef } from 'react';\n\n// ------------ //\n// SEARCH INPUT //\n// ------------ //\n\ninterface SearchInputProps {\n term: string;\n selectedIcon: string | null;\n onChange: ChangeEventHandler<HTMLInputElement>;\n}\n\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>((props, ref) => {\n const { term, selectedIcon, onChange } = props;\n\n return (\n <Combobox.Input\n as={TextInput}\n ref={ref}\n inputMode=\"search\"\n value={term}\n onChange={onChange}\n icon={selectedIcon ? <Icon icon={selectedIcon} /> : null}\n placeholder={selectedIcon ? 'Search and replace selected icon...' : 'Search for an icon...'}\n />\n );\n});\n\nSearchInput.displayName = 'SearchInput';\n","import { Combobox } from '@headlessui/react';\nimport { Icon } from '@iconify/react';\nimport { Button } from '@sanity/ui';\n\nimport { MessageWrapper } from './iconify-combobox.styles';\n\n// -------------- //\n// SEARCH RESULTS //\n// -------------- //\n\nexport interface SearchResultsProps {\n state: 'initial' | 'loading' | 'error' | 'empty' | 'data' | 'stale';\n data?: string[];\n}\n\nexport function SearchResults(props: SearchResultsProps) {\n const { state, data } = props;\n\n if (state === 'initial') {\n return <MessageWrapper>Search for icons</MessageWrapper>;\n }\n\n if (state === 'loading') {\n return <MessageWrapper>Searching...</MessageWrapper>;\n }\n\n if (state === 'error') {\n return <MessageWrapper>Something went wrong...</MessageWrapper>;\n }\n\n if (state === 'empty') {\n return <MessageWrapper>No icons found</MessageWrapper>;\n }\n\n return (\n <Combobox.Options style={{ opacity: state === 'stale' ? 0.5 : 1 }}>\n {data!.map((icon) => (\n <Combobox.Option key={icon} value={icon}>\n {({ active }) => (\n <Button padding={3} mode=\"bleed\" selected={active}>\n <Icon icon={icon} width=\"100%\" height=\"100%\" />\n </Button>\n )}\n </Combobox.Option>\n ))}\n </Combobox.Options>\n );\n}\n","import { TrashIcon } from '@sanity/icons';\nimport { Button, Card } from '@sanity/ui';\n\n// ------------ //\n// UNSET BUTTON //\n// ------------ //\n\ninterface UnsetButtonProps {\n onUnset: () => void;\n}\n\nexport function UnsetButton(props: UnsetButtonProps) {\n const { onUnset } = props;\n\n return (\n <Card border borderLeft={false} padding={1} display=\"flex\">\n <Button icon={<TrashIcon />} onClick={onUnset} mode=\"bleed\" fontSize={1} padding={2} />\n </Card>\n );\n}\n","import { Combobox } from '@headlessui/react';\nimport { Popover, useToast } from '@sanity/ui';\nimport { ChangeEventHandler, useCallback, useEffect, useId, useRef } from 'react';\nimport { match } from 'ts-pattern';\n\nimport { useSearch } from '../lib/api';\nimport { ComboboxWrapper, OptionsWrapper } from './iconify-combobox.styles';\nimport { SearchInput } from './search-input';\nimport { SearchResults, SearchResultsProps } from './search-result';\nimport { UnsetButton } from './unset-button';\n\nexport interface IconifyComboboxProps {\n selectedIcon: string | null;\n onSelect: (newValue: string) => void;\n collections: string[] | null;\n}\n\nexport function IconifyCombobox(props: IconifyComboboxProps) {\n const { selectedIcon, onSelect: pushSelection, collections } = props;\n\n const id = useId();\n const toast = useToast();\n const inputRef = useRef<HTMLInputElement>(null);\n\n const { term, setTerm, debouncedTerm, isLoading, isError, error, data, isPreviousData } =\n useSearch({\n collections,\n });\n\n const handleTermChange: ChangeEventHandler<HTMLInputElement> = useCallback(\n (event) => setTerm(event.target.value),\n [setTerm],\n );\n\n const handleSelect = useCallback(\n (icon: string) => {\n pushSelection(icon);\n setTerm('', true);\n },\n [pushSelection, setTerm],\n );\n\n const handleUnset = useCallback(() => handleSelect(''), [handleSelect]);\n\n useEffect(() => {\n if (isError) {\n console.error('Iconify input error:', error);\n\n toast.push({\n id,\n status: 'error',\n title: 'Iconify input error',\n description: error?.message,\n });\n }\n }, [error, id, isError, toast]);\n\n return (\n <ComboboxWrapper>\n <Combobox onChange={handleSelect}>\n {({ open }) => (\n <>\n <SearchInput\n ref={inputRef}\n term={term}\n selectedIcon={selectedIcon}\n onChange={handleTermChange}\n />\n\n <Popover\n open={open}\n placement=\"bottom\"\n arrow={false}\n matchReferenceWidth\n portal\n constrainSize\n referenceElement={inputRef.current}\n content={\n <OptionsWrapper>\n <SearchResults\n state={match<boolean>(true)\n .returnType<SearchResultsProps['state']>()\n .with(isLoading, () => 'loading')\n .with(!debouncedTerm, () => 'initial')\n .with(isError, () => 'error')\n .with(!data || data.length === 0, () => 'empty')\n .with(isPreviousData, () => 'stale')\n .otherwise(() => 'data')}\n data={data}\n />\n </OptionsWrapper>\n }\n />\n </>\n )}\n </Combobox>\n\n {selectedIcon ? <UnsetButton onUnset={handleUnset} /> : null}\n </ComboboxWrapper>\n );\n}\n","import {\n QueryClient,\n QueryClientProvider as ReactQueryClientProvider,\n} from '@tanstack/react-query';\nimport { ReactNode } from 'react';\n\nexport const queryClient = new QueryClient();\n\nexport function QueryClientProvider(props: { children: ReactNode }) {\n return <ReactQueryClientProvider client={queryClient}>{props.children}</ReactQueryClientProvider>;\n}\n","import { IconifyIconName, stringToIcon } from '@iconify/utils';\nimport { sentenceCase } from 'change-case';\nimport { useMemo } from 'react';\n\nimport { useIconSetInfo } from './api';\n\ninterface UsePrettyIconNameProps {\n name?: string | null;\n iconMeta?: IconifyIconName | null;\n}\n\nexport function usePrettyIconName(props: UsePrettyIconNameProps) {\n const { name } = props;\n const iconMeta = useMemo(\n () => props.iconMeta ?? (name ? stringToIcon(name) : null),\n [name, props.iconMeta],\n );\n const iconSetInfo = useIconSetInfo({ prefix: iconMeta?.prefix ?? null });\n\n return useMemo(\n () =>\n iconMeta\n ? {\n name: sentenceCase(iconMeta.name),\n collection: iconSetInfo.data?.name ?? iconMeta.prefix,\n }\n : null,\n [iconMeta, iconSetInfo.data?.name],\n );\n}\n","import { Flex, RootTheme, Stack, studioTheme, Text, ThemeProvider, useTheme } from '@sanity/ui';\nimport { useCallback, useMemo } from 'react';\nimport { ObjectInputProps, set, unset } from 'sanity';\n\nimport { IconifyCombobox } from './combobox';\nimport { QueryClientProvider } from './lib/query-client';\nimport { IconifyPluginConfig, IconOptions } from './lib/types';\nimport { usePrettyIconName } from './lib/use-pretty-icon-name';\n\n// -------------- //\n// ICONIFY INPUT //\n// -------------- //\n\ninterface IconifyInputProps extends ObjectInputProps {\n config: IconifyPluginConfig;\n}\n\nexport function IconifyInput(props: IconifyInputProps) {\n const { config, value, onChange: pushChange, schemaType } = props;\n\n const selectedIcon: string | null = value?.name ?? null;\n\n const options: IconOptions = schemaType.options;\n const collections =\n (!!options?.collections?.length && options.collections) ||\n (!!config?.collections?.length && config.collections) ||\n null;\n const showName = options?.showName ?? config?.showName ?? false;\n\n const parentTheme = useTheme();\n const theme: RootTheme = useMemo(\n () => (parentTheme ? { ...parentTheme.sanity, color: studioTheme.color } : studioTheme),\n [parentTheme],\n );\n\n const handleSelect = useCallback(\n (icon: string) => {\n pushChange(icon === '' ? unset() : set(icon, ['name']));\n },\n [pushChange],\n );\n\n return (\n <QueryClientProvider>\n <ThemeProvider theme={theme}>\n <Stack space={2}>\n <IconifyCombobox\n selectedIcon={selectedIcon}\n onSelect={handleSelect}\n collections={collections}\n />\n\n {showName && selectedIcon ? <IconifyNameDisplay name={selectedIcon} /> : null}\n </Stack>\n </ThemeProvider>\n </QueryClientProvider>\n );\n}\n\ninterface IconifyNameDisplayProps {\n name?: string | null;\n}\n\nfunction IconifyNameDisplay(props: IconifyNameDisplayProps) {\n const { name } = props;\n const prettyName = usePrettyIconName({ name });\n\n return (\n <Flex gap={1}>\n <Text size={1} muted>\n Selected:\n </Text>\n\n <Text size={1} weight=\"semibold\">\n {prettyName?.name ?? name}\n </Text>\n\n {prettyName?.collection && (\n <Text size={1} muted style={{ fontStyle: 'italic' }}>\n by {prettyName?.collection}\n </Text>\n )}\n </Flex>\n );\n}\n","import { Icon } from '@iconify/react';\nimport { IconifyIconName, stringToIcon } from '@iconify/utils';\nimport { PreviewProps } from 'sanity';\n\nimport { QueryClientProvider } from './lib/query-client';\nimport { usePrettyIconName } from './lib/use-pretty-icon-name';\n\n// --------------- //\n// ICONIFY PREVIEW //\n// --------------- //\n\nexport function IconifyPreview(props: PreviewProps) {\n const { title } = props;\n const iconName = typeof props.title === 'string' ? stringToIcon(props.title) : null;\n\n // We check this double to avoid the TS error\n if (typeof title === 'string' && iconName) {\n return (\n <QueryClientProvider>\n <IconifyPreviewInner {...props} iconName={title} iconMeta={iconName} />\n </QueryClientProvider>\n );\n }\n\n return props.renderDefault(props);\n}\n\n// --------------------- //\n// ICONIFY PREVIEW INNER //\n// --------------------- //\n\ninterface IconifyPreviewInnerProps extends PreviewProps {\n iconName: string;\n iconMeta: IconifyIconName;\n}\n\nfunction IconifyPreviewInner(props: IconifyPreviewInnerProps) {\n const { iconMeta, iconName, ...previewProps } = props;\n const prettyName = usePrettyIconName({ iconMeta });\n\n return props.renderDefault({\n ...previewProps,\n media: <Icon icon={iconName} />,\n title: prettyName?.name ?? iconName,\n subtitle: prettyName?.collection,\n });\n}\n","import { definePlugin, FieldProps, ObjectInputProps } from 'sanity';\n\nimport { IconifyInput } from './iconify-input';\nimport { IconifyPreview } from './iconify-preview';\nimport { IconifyPluginConfig } from './lib/types';\n\n/**\n * Usage in `sanity.config.ts` (or .js)\n *\n * ```ts\n * import { defineConfig } from 'sanity'\n * import { iconify } from 'sanity-plugin-iconify'\n *\n * export default defineConfig({\n * // ...\n * plugins: [iconify()],\n * })\n * ```\n */\nexport const iconify = definePlugin<IconifyPluginConfig | void>((config = {}) => {\n return {\n name: 'sanity-plugin-iconify',\n schema: {\n types: [\n {\n name: 'icon',\n title: 'Icon',\n type: 'object',\n fields: [\n {\n name: 'name',\n title: 'Name',\n type: 'string',\n },\n ],\n components: {\n input: (props: ObjectInputProps) => <IconifyInput {...props} config={config!} />,\n preview: IconifyPreview,\n\n // This makes sure the input component is not indented\n field: (props: FieldProps) => props.renderDefault({ ...props, level: 0 }),\n },\n },\n ],\n },\n };\n});\n"],"names":["queryClient","useQueryClient","useState","useDebounce","useCallback","useQuery","keepPreviousData","styled","Grid","Box","jsx","Card","Text","forwardRef","Combobox","TextInput","Icon","Button","TrashIcon","useId","useToast","useRef","useEffect","jsxs","Fragment","Popover","match","QueryClient","ReactQueryClientProvider","useMemo","_a","stringToIcon","_b","sentenceCase","useTheme","studioTheme","unset","set","ThemeProvider","Stack","Flex","definePlugin"],"mappings":";;;;;;;AAOA,MAAM,eAAe;AAErB,SAAS,UAAa,EAAE,KAAK,UAAmE;AACvF,SAAA,MAAM,KAAK,EAAE,OAAQ,CAAA,EACzB,KAAK,CAAC,aAAa;AAClB,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,yBAAyB,SAAS,MAAM,EAAE;AAG5D,WAAO,SAAS;EACjB,CAAA,EACA;AAAA,IACC,CAAC,WAAW;AAAA,IACZ,CAAC,UAAU;AACL,YAAA,iBAAiB,QACb,SAEN,QAAQ,MAAM,kBAAkB,KAAK,EAAE,GACjC,IAAI,MAAM,sBAAsB;AAAA,IAE1C;AAAA,EAAA;AAEN;AAEgB,SAAA,UAAU,EAAE,eAAiD;AAC3E,QAAMA,eAAcC,WAAAA,kBACd,CAAC,MAAM,OAAO,IAAIC,MAAAA,SAAS,EAAE,GAC7B,CAAC,eAAe,gBAAgB,IAAIC,wBAAY,MAAM,GAAG,GAEzD,aAAaC,MAAA;AAAA,IACjB,CAAC,SAAiB,oBAAoB,OAAU;AAC9C,cAAQ,OAAO,GAEX,qBACF,iBAAiB,OAAO;AAAA,IAE5B;AAAA,IACA,CAAC,gBAAgB;AAAA,EAAA,GAGb,EAAE,WAAW,SAAS,OAAO,MAAM,sBAAsBC,oBAA0B;AAAA,IACvF,UAAU,CAAC,UAAU,aAAa,aAAa;AAAA,IAC/C,SAAS,OAAO,EAAE,aAAa;AAjDnC,UAAA;AAkDM,YAAM,MAAM,IAAI,IAAI,WAAW,YAAY;AAE3C,UAAI,aAAa,OAAO,SAAS,aAAa,GAC9C,IAAI,aAAa,OAAO,SAAS,IAAI,GAEjC,eACF,IAAI,aAAa,OAAO,YAAY,YAAY,KAAK,GAAG,CAAC;AAGrD,YAAA,SAAS,gBAAgB,MAAM,UAA+B,EAAE,KAAK,OAAA,CAAQ,IAAI;AAEnF,aAAA,UAEF,OAAO,QAAQ,OAAO,WAAW,EAAE,QAAQ,CAAC,CAAC,QAAQ,IAAI,MAAM;AAC7D,QAAAL,aAAY,aAA0B,CAAC,eAAe,MAAM,GAAG,IAAI;AAAA,MACpE,CAAA,IAGI,KAAQ,UAAA,OAAA,SAAA,OAAA,UAAR,YAAiB,CAAA;AAAA,IAC1B;AAAA,IACA,SAAS,cAAc,SAAS;AAAA,IAChC,iBAAiBM,WAAA;AAAA,IACjB,WAAW,IAAI,KAAK;AAAA;AAAA,EAAA,CACrB;AAEM,SAAA;AAAA,IACL;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,EAAA;AAEpB;AAEgB,SAAA,eAAe,EAAE,UAAsC;AACrE,SAAOD,oBAAoC;AAAA,IACzC,UAAU,CAAC,eAAe,MAAM;AAAA,IAChC,SAAS,OAAO,EAAE,aAAa;AA1FnC,UAAA;AA2FM,UAAI,CAAC;AAAe,eAAA;AAEpB,YAAM,MAAM,IAAI,IAAI,eAAe,YAAY;AAE3C,UAAA,aAAa,OAAO,UAAU,MAAM,GACxC,IAAI,aAAa,OAAO,QAAQ,MAAM;AAEtC,YAAM,SAAS,MAAM,UAAiC,EAAE,KAAK,OAAQ,CAAA;AAE9D,cAAA,KAAA,UAAA,OAAA,SAAA,OAAQ,SAAR,OAAgB,KAAA;AAAA,IACzB;AAAA,IACA,WAAW;AAAA,EAAA,CACZ;AACH;ACpGa,MAAA,kBAAkBE,gBAAAA,QAAOC,GAAAA,IAAI;AAAA;AAAA;AAAA,GAK7B,iBAAiBD,wBAAOE,GAAAA,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiCxB,SAAA,eAAe,EAAE,YAAqC;AAElE,SAAAC,2BAAAA,IAACC,GAAAA,MAAK,EAAA,SAAS,GACb,UAAAD,+BAACE,GAAAA,MAAK,EAAA,OAAM,UAAS,OAAK,IACvB,SAAA,CACH,EACF,CAAA;AAEJ;ACnCO,MAAM,cAAcC,MAAA,WAA+C,CAAC,OAAO,QAAQ;AACxF,QAAM,EAAE,MAAM,cAAc,SAAA,IAAa;AAGvC,SAAAH,2BAAA;AAAA,IAACI,QAAAA,SAAS;AAAA,IAAT;AAAA,MACC,IAAIC,GAAA;AAAA,MACJ;AAAA,MACA,WAAU;AAAA,MACV,OAAO;AAAA,MACP;AAAA,MACA,MAAM,eAAeL,+BAACM,QAAAA,MAAK,EAAA,MAAM,aAAc,CAAA,IAAK;AAAA,MACpD,aAAa,eAAe,wCAAwC;AAAA,IAAA;AAAA,EAAA;AAG1E,CAAC;AAED,YAAY,cAAc;AChBnB,SAAS,cAAc,OAA2B;AACjD,QAAA,EAAE,OAAO,KAAS,IAAA;AAExB,SAAI,UAAU,YACJN,2BAAA,IAAA,gBAAA,EAAe,8BAAgB,IAGrC,UAAU,YACLA,2BAAA,IAAC,gBAAe,EAAA,UAAA,eAAA,CAAY,IAGjC,UAAU,UACJA,2BAAA,IAAA,gBAAA,EAAe,UAAuB,2BAAA,IAG5C,UAAU,UACJA,2BAAAA,IAAA,gBAAA,EAAe,4BAAc,IAIrCA,2BAAA,IAACI,iBAAS,SAAT,EAAiB,OAAO,EAAE,SAAS,UAAU,UAAU,MAAM,EAAE,GAC7D,UAAM,KAAA,IAAI,CAAC,wCACTA,QAAS,SAAA,QAAT,EAA2B,OAAO,MAChC,UAAA,CAAC,EAAE,aACDJ,2BAAAA,IAAAO,GAAAA,QAAA,EAAO,SAAS,GAAG,MAAK,SAAQ,UAAU,QACzC,yCAACD,QAAK,MAAA,EAAA,MAAY,OAAM,QAAO,QAAO,QAAO,EAAA,CAC/C,EAJkB,GAAA,IAMtB,CACD,EACH,CAAA;AAEJ;ACpCO,SAAS,YAAY,OAAyB;AAC7C,QAAA,EAAE,QAAY,IAAA;AAGlB,SAAAN,2BAAA,IAACC,GAAK,MAAA,EAAA,QAAM,IAAC,YAAY,IAAO,SAAS,GAAG,SAAQ,QAClD,UAACD,2BAAAA,IAAAO,GAAAA,QAAA,EAAO,MAAOP,2BAAA,IAAAQ,MAAA,WAAA,CAAU,CAAA,GAAI,SAAS,SAAS,MAAK,SAAQ,UAAU,GAAG,SAAS,EAAG,CAAA,EACvF,CAAA;AAEJ;ACFO,SAAS,gBAAgB,OAA6B;AACrD,QAAA,EAAE,cAAc,UAAU,eAAe,YAAgB,IAAA,OAEzD,KAAKC,MAAA,MAAA,GACL,QAAQC,GAAS,SAAA,GACjB,WAAWC,MAAA,OAAyB,IAAI,GAExC,EAAE,MAAM,SAAS,eAAe,WAAW,SAAS,OAAO,MAAM,eAAe,IACpF,UAAU;AAAA,IACR;AAAA,EAAA,CACD,GAEG,mBAAyDjB,MAAA;AAAA,IAC7D,CAAC,UAAU,QAAQ,MAAM,OAAO,KAAK;AAAA,IACrC,CAAC,OAAO;AAAA,KAGJ,eAAeA,MAAA;AAAA,IACnB,CAAC,SAAiB;AAChB,oBAAc,IAAI,GAClB,QAAQ,IAAI,EAAI;AAAA,IAClB;AAAA,IACA,CAAC,eAAe,OAAO;AAAA,EAAA,GAGnB,cAAcA,MAAAA,YAAY,MAAM,aAAa,EAAE,GAAG,CAAC,YAAY,CAAC;AAEtE,SAAAkB,MAAA,UAAU,MAAM;AACV,gBACF,QAAQ,MAAM,wBAAwB,KAAK,GAE3C,MAAM,KAAK;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,aAAa,SAAO,OAAA,SAAA,MAAA;AAAA,IACrB,CAAA;AAAA,EAAA,GAEF,CAAC,OAAO,IAAI,SAAS,KAAK,CAAC,GAG5BC,2BAAA,KAAC,iBACC,EAAA,UAAA;AAAA,IAAAb,2BAAAA,IAACI,oBAAS,UAAU,cACjB,WAAC,EAAE,WAEAS,2BAAAA,KAAAC,WAAA,UAAA,EAAA,UAAA;AAAA,MAAAd,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK;AAAA,UACL;AAAA,UACA;AAAA,UACA,UAAU;AAAA,QAAA;AAAA,MACZ;AAAA,MAEAA,2BAAA;AAAA,QAACe,GAAA;AAAA,QAAA;AAAA,UACC;AAAA,UACA,WAAU;AAAA,UACV,OAAO;AAAA,UACP,qBAAmB;AAAA,UACnB,QAAM;AAAA,UACN,eAAa;AAAA,UACb,kBAAkB,SAAS;AAAA,UAC3B,wCACG,gBACC,EAAA,UAAAf,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,OAAOgB,UAAe,MAAA,EAAI,EACvB,WAAA,EACA,KAAK,WAAW,MAAM,SAAS,EAC/B,KAAK,CAAC,eAAe,MAAM,SAAS,EACpC,KAAK,SAAS,MAAM,OAAO,EAC3B,KAAK,CAAC,QAAQ,KAAK,WAAW,GAAG,MAAM,OAAO,EAC9C,KAAK,gBAAgB,MAAM,OAAO,EAClC,UAAU,MAAM,MAAM;AAAA,cACzB;AAAA,YAAA;AAAA,UAAA,GAEJ;AAAA,QAAA;AAAA,MAEJ;AAAA,IAAA,EAAA,CACF,EAEJ,CAAA;AAAA,IAEC,eAAehB,2BAAA,IAAC,aAAY,EAAA,SAAS,YAAa,CAAA,IAAK;AAAA,EAC1D,EAAA,CAAA;AAEJ;AC9Fa,MAAA,cAAc,IAAIiB,WAAAA;AAExB,SAAS,oBAAoB,OAAgC;AAClE,SAAQjB,2BAAA,IAAAkB,WAAA,qBAAA,EAAyB,QAAQ,aAAc,gBAAM,SAAS,CAAA;AACxE;ACCO,SAAS,kBAAkB,OAA+B;AAXjE,MAAA,IAAA;AAYE,QAAM,EAAE,KAAA,IAAS,OACX,WAAWC,MAAA;AAAA,IACf,MAAG;AAdPC,UAAAA;AAcUA,cAAAA,MAAA,MAAM,aAAN,OAAAA,MAAmB,OAAOC,MAAA,aAAa,IAAI,IAAI;AAAA,IAAA;AAAA,IACrD,CAAC,MAAM,MAAM,QAAQ;AAAA,EAAA,GAEjB,cAAc,eAAe,EAAE,SAAQ,KAAU,YAAA,OAAA,SAAA,SAAA,WAAV,OAAoB,KAAA,KAAA,CAAM;AAEhE,SAAAF,MAAA;AAAA,IACL,MAAG;AApBP,UAAAC,KAAAE;AAsBU,aAAA,WAAA;AAAA,QACE,MAAMC,WAAAA,aAAa,SAAS,IAAI;AAAA,QAChC,aAAYD,OAAAF,MAAA,YAAY,SAAZ,gBAAAA,IAAkB,SAAlB,OAAAE,MAA0B,SAAS;AAAA,MAEjD,IAAA;AAAA,IAAA;AAAA,IACN,CAAC,WAAU,KAAY,YAAA,SAAZ,mBAAkB,IAAI;AAAA,EAAA;AAErC;ACZO,SAAS,aAAa,OAA0B;AAjBvD,MAAA,IAAA,IAAA,IAAA,IAAA;AAkBQ,QAAA,EAAE,QAAQ,OAAO,UAAU,YAAY,WAAW,IAAI,OAEtD,gBAA8B,KAAA,SAAA,OAAA,SAAA,MAAO,SAAP,OAAe,KAAA,MAE7C,UAAuB,WAAW,SAClC,cACH,CAAC,GAAC,wCAAS,gBAAT,QAAA,GAAsB,WAAU,QAAQ,eAC1C,CAAC,GAAC,KAAA,UAAA,OAAA,SAAA,OAAQ,gBAAR,QAAqB,GAAA,WAAU,OAAO,eACzC,MACI,YAAW,MAAS,KAAA,WAAA,OAAA,SAAA,QAAA,aAAT,YAAqB,UAAQ,OAAA,SAAA,OAAA,aAA7B,YAAyC,IAEpD,cAAcE,GAAS,SAAA,GACvB,QAAmBL,MAAA;AAAA,IACvB,MAAO,cAAc,EAAE,GAAG,YAAY,QAAQ,OAAOM,GAAY,YAAA,MAAA,IAAUA,GAAA;AAAA,IAC3E,CAAC,WAAW;AAAA,KAGR,eAAe/B,MAAA;AAAA,IACnB,CAAC,SAAiB;AACL,iBAAA,SAAS,KAAKgC,aAAM,IAAIC,WAAI,MAAM,CAAC,MAAM,CAAC,CAAC;AAAA,IACxD;AAAA,IACA,CAAC,UAAU;AAAA,EAAA;AAIX,SAAA3B,2BAAA,IAAC,uBACC,UAACA,2BAAAA,IAAA4B,GAAAA,eAAA,EAAc,OACb,UAACf,2BAAA,KAAAgB,GAAA,OAAA,EAAM,OAAO,GACZ,UAAA;AAAA,IAAA7B,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,UAAU;AAAA,QACV;AAAA,MAAA;AAAA,IACF;AAAA,IAEC,YAAY,eAAeA,+BAAC,oBAAmB,EAAA,MAAM,aAAc,CAAA,IAAK;AAAA,EAAA,GAC3E,GACF,EACF,CAAA;AAEJ;AAMA,SAAS,mBAAmB,OAAgC;AA/D5D,MAAA;AAgEQ,QAAA,EAAE,SAAS,OACX,aAAa,kBAAkB,EAAE,MAAM;AAG3C,SAAAa,2BAAA,KAACiB,GAAK,MAAA,EAAA,KAAK,GACT,UAAA;AAAA,IAAA9B,+BAACE,GAAAA,MAAK,EAAA,MAAM,GAAG,OAAK,IAAC,UAErB,aAAA;AAAA,IAEAF,2BAAA,IAACE,WAAK,MAAM,GAAG,QAAO,YACnB,WAAA,KAAA,cAAA,OAAA,SAAA,WAAY,SAAZ,OAAA,KAAoB,MACvB;AAAA,KAEC,cAAY,OAAA,SAAA,WAAA,eACVW,2BAAA,KAAAX,SAAA,EAAK,MAAM,GAAG,OAAK,IAAC,OAAO,EAAE,WAAW,SAAY,GAAA,UAAA;AAAA,MAAA;AAAA,MAC/C,cAAY,OAAA,SAAA,WAAA;AAAA,IAAA,GAClB;AAAA,EAEJ,EAAA,CAAA;AAEJ;ACzEO,SAAS,eAAe,OAAqB;AAClD,QAAM,EAAE,MAAU,IAAA,OACZ,WAAW,OAAO,MAAM,SAAU,WAAWmB,MAAAA,aAAa,MAAM,KAAK,IAAI;AAG/E,SAAI,OAAO,SAAU,YAAY,WAE5BrB,2BAAAA,IAAA,qBAAA,EACC,yCAAC,qBAAqB,EAAA,GAAG,OAAO,UAAU,OAAO,UAAU,SAAA,CAAU,EACvE,CAAA,IAIG,MAAM,cAAc,KAAK;AAClC;AAWA,SAAS,oBAAoB,OAAiC;AApC9D,MAAA;AAqCQ,QAAA,EAAE,UAAU,UAAU,GAAG,aAAiB,IAAA,OAC1C,aAAa,kBAAkB,EAAE,SAAA,CAAU;AAEjD,SAAO,MAAM,cAAc;AAAA,IACzB,GAAG;AAAA,IACH,OAAOA,2BAAAA,IAACM,QAAAA,MAAK,EAAA,MAAM,SAAU,CAAA;AAAA,IAC7B,QAAO,KAAY,cAAA,OAAA,SAAA,WAAA,SAAZ,OAAoB,KAAA;AAAA,IAC3B,UAAU,cAAY,OAAA,SAAA,WAAA;AAAA,EAAA,CACvB;AACH;AC3BO,MAAM,UAAUyB,OAAA,aAAyC,CAAC,SAAS,QACjE;AAAA,EACL,MAAM;AAAA,EACN,QAAQ;AAAA,IACN,OAAO;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ;AAAA,UACN;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA,YACP,MAAM;AAAA,UACR;AAAA,QACF;AAAA,QACA,YAAY;AAAA,UACV,OAAO,CAAC,yCAA6B,cAAc,EAAA,GAAG,OAAO,QAAiB;AAAA,UAC9E,SAAS;AAAA;AAAA,UAGT,OAAO,CAAC,UAAsB,MAAM,cAAc,EAAE,GAAG,OAAO,OAAO,GAAG;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF,EACD;;"}
@@ -0,0 +1,218 @@
1
+ import { BaseSchemaDefinition } from 'sanity';
2
+ import { IconifyInfo } from '@iconify/types';
3
+ import { Plugin as Plugin_2 } from 'sanity';
4
+
5
+ export { BaseSchemaDefinition };
6
+
7
+ /**
8
+ * Usage in `sanity.config.ts` (or .js)
9
+ *
10
+ * ```ts
11
+ * import { defineConfig } from 'sanity'
12
+ * import { iconify } from 'sanity-plugin-iconify'
13
+ *
14
+ * export default defineConfig({
15
+ * // ...
16
+ * plugins: [iconify()],
17
+ * })
18
+ * ```
19
+ */
20
+ export declare const iconify: Plugin_2<void | IconifyPluginConfig>;
21
+
22
+ export declare interface IconifyPluginConfig {
23
+ collections?: IconPrefix[];
24
+ showName?: boolean;
25
+ }
26
+
27
+ export declare interface IconifySearchResult {
28
+ icons: string[];
29
+ collections: Record<string, IconifyInfo>;
30
+ }
31
+
32
+ export declare interface IconOptions {
33
+ collections?: IconPrefix[];
34
+ showName?: boolean;
35
+ }
36
+
37
+ export declare type IconPrefix =
38
+ | 'material-symbols'
39
+ | 'material-symbols-light'
40
+ | 'ic'
41
+ | 'mdi'
42
+ | 'ph'
43
+ | 'solar'
44
+ | 'tabler'
45
+ | 'mingcute'
46
+ | 'ri'
47
+ | 'bi'
48
+ | 'carbon'
49
+ | 'iconamoon'
50
+ | 'iconoir'
51
+ | 'ion'
52
+ | 'lucide'
53
+ | 'uil'
54
+ | 'tdesign'
55
+ | 'teenyicons'
56
+ | 'clarity'
57
+ | 'bx'
58
+ | 'bxs'
59
+ | 'majesticons'
60
+ | 'ant-design'
61
+ | 'gg'
62
+ | 'gravity-ui'
63
+ | 'octicon'
64
+ | 'memory'
65
+ | 'cil'
66
+ | 'flowbite'
67
+ | 'mynaui'
68
+ | 'basil'
69
+ | 'pixelarticons'
70
+ | 'akar-icons'
71
+ | 'ci'
72
+ | 'system-uicons'
73
+ | 'typcn'
74
+ | 'radix-icons'
75
+ | 'zondicons'
76
+ | 'ep'
77
+ | 'circum'
78
+ | 'mdi-light'
79
+ | 'fe'
80
+ | 'eos-icons'
81
+ | 'bitcoin-icons'
82
+ | 'charm'
83
+ | 'prime'
84
+ | 'humbleicons'
85
+ | 'uiw'
86
+ | 'uim'
87
+ | 'uit'
88
+ | 'uis'
89
+ | 'maki'
90
+ | 'gridicons'
91
+ | 'mi'
92
+ | 'quill'
93
+ | 'gala'
94
+ | 'lets-icons'
95
+ | 'f7'
96
+ | 'mage'
97
+ | 'fluent'
98
+ | 'icon-park-outline'
99
+ | 'icon-park-solid'
100
+ | 'icon-park-twotone'
101
+ | 'icon-park'
102
+ | 'vscode-icons'
103
+ | 'jam'
104
+ | 'heroicons'
105
+ | 'codicon'
106
+ | 'pajamas'
107
+ | 'pepicons-pop'
108
+ | 'pepicons-print'
109
+ | 'pepicons-pencil'
110
+ | 'bytesize'
111
+ | 'ei'
112
+ | 'streamline'
113
+ | 'guidance'
114
+ | 'fa6-solid'
115
+ | 'fa6-regular'
116
+ | 'ooui'
117
+ | 'nimbus'
118
+ | 'oui'
119
+ | 'formkit'
120
+ | 'line-md'
121
+ | 'meteocons'
122
+ | 'svg-spinners'
123
+ | 'openmoji'
124
+ | 'twemoji'
125
+ | 'noto'
126
+ | 'fluent-emoji'
127
+ | 'fluent-emoji-flat'
128
+ | 'fluent-emoji-high-contrast'
129
+ | 'noto-v1'
130
+ | 'emojione'
131
+ | 'emojione-monotone'
132
+ | 'emojione-v1'
133
+ | 'fxemoji'
134
+ | 'streamline-emojis'
135
+ | 'bxl'
136
+ | 'logos'
137
+ | 'simple-icons'
138
+ | 'cib'
139
+ | 'fa6-brands'
140
+ | 'nonicons'
141
+ | 'arcticons'
142
+ | 'cbi'
143
+ | 'file-icons'
144
+ | 'devicon'
145
+ | 'devicon-plain'
146
+ | 'skill-icons'
147
+ | 'unjs'
148
+ | 'brandico'
149
+ | 'entypo-social'
150
+ | 'cryptocurrency'
151
+ | 'cryptocurrency-color'
152
+ | 'flag'
153
+ | 'circle-flags'
154
+ | 'flagpack'
155
+ | 'cif'
156
+ | 'gis'
157
+ | 'map'
158
+ | 'geo'
159
+ | 'game-icons'
160
+ | 'fad'
161
+ | 'academicons'
162
+ | 'wi'
163
+ | 'healthicons'
164
+ | 'medical-icon'
165
+ | 'covid'
166
+ | 'la'
167
+ | 'eva'
168
+ | 'dashicons'
169
+ | 'flat-color-icons'
170
+ | 'entypo'
171
+ | 'foundation'
172
+ | 'raphael'
173
+ | 'icons8'
174
+ | 'iwwa'
175
+ | 'heroicons-outline'
176
+ | 'heroicons-solid'
177
+ | 'fa-solid'
178
+ | 'fa-regular'
179
+ | 'fa-brands'
180
+ | 'fa'
181
+ | 'fluent-mdl2'
182
+ | 'fontisto'
183
+ | 'icomoon-free'
184
+ | 'subway'
185
+ | 'oi'
186
+ | 'wpf'
187
+ | 'simple-line-icons'
188
+ | 'et'
189
+ | 'el'
190
+ | 'vaadin'
191
+ | 'grommet-icons'
192
+ | 'whh'
193
+ | 'si-glyph'
194
+ | 'zmdi'
195
+ | 'ls'
196
+ | 'bpmn'
197
+ | 'flat-ui'
198
+ | 'vs'
199
+ | 'topcoat'
200
+ | 'il'
201
+ | 'websymbol'
202
+ | 'fontelico'
203
+ | 'ps'
204
+ | 'feather'
205
+ | 'mono-icons'
206
+ | 'pepicons';
207
+
208
+ export {};
209
+
210
+ declare module 'sanity' {
211
+ interface IconDefinition extends BaseSchemaDefinition {
212
+ type: 'icon';
213
+ options?: IconOptions;
214
+ }
215
+ interface IntrinsicDefinitions {
216
+ icon: IconDefinition;
217
+ }
218
+ }