sanity-plugin-iconify 2.0.0 → 2.0.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/dist/index.cjs +78 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +136 -59
- package/dist/index.d.ts +136 -59
- package/dist/index.js +76 -65
- package/dist/index.js.map +1 -1
- package/package.json +52 -45
- package/src/combobox/iconify-combobox.styles.tsx +7 -7
- package/src/combobox/iconify-combobox.tsx +64 -53
- package/src/combobox/search-input.tsx +4 -14
- package/src/combobox/search-result.tsx +36 -35
- package/src/iconify-input.tsx +1 -11
- package/src/lib/icon-types.gen.ts +1 -0
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
-
var jsxRuntime = require("react/jsx-runtime"), sanity = require("sanity"), ui = require("@sanity/ui"), theme = require("@sanity/ui/theme"), react = require("react"),
|
|
3
|
+
var jsxRuntime = require("react/jsx-runtime"), sanity = require("sanity"), ui = require("@sanity/ui"), theme = require("@sanity/ui/theme"), react = require("react"), downshift = require("downshift"), tsPattern = require("ts-pattern"), reactQuery = require("@tanstack/react-query"), useDebounce = require("use-debounce"), styled = require("styled-components"), react$1 = require("@iconify/react"), icons = require("@sanity/icons"), utils = require("@iconify/utils"), changeCase = require("change-case");
|
|
4
4
|
function _interopDefaultCompat(e) {
|
|
5
5
|
return e && typeof e == "object" && "default" in e ? e : { default: e };
|
|
6
6
|
}
|
|
@@ -27,13 +27,12 @@ function useSearch({ collections }) {
|
|
|
27
27
|
), { isLoading, isError, error, data, isPlaceholderData } = reactQuery.useQuery({
|
|
28
28
|
queryKey: ["search", collections, debouncedTerm],
|
|
29
29
|
queryFn: async ({ signal }) => {
|
|
30
|
-
var _a;
|
|
31
30
|
const url = new URL("/search", BASE_API_URL);
|
|
32
31
|
url.searchParams.append("query", debouncedTerm), url.searchParams.append("limit", "60"), collections && url.searchParams.append("prefixes", collections.join(","));
|
|
33
32
|
const result = debouncedTerm ? await fetchJson({ url, signal }) : null;
|
|
34
33
|
return result && Object.entries(result.collections).forEach(([prefix, info]) => {
|
|
35
34
|
queryClient2.setQueryData(["iconSetInfo", prefix], info);
|
|
36
|
-
}),
|
|
35
|
+
}), result?.icons ?? [];
|
|
37
36
|
},
|
|
38
37
|
enabled: debouncedTerm.length > 0,
|
|
39
38
|
placeholderData: reactQuery.keepPreviousData,
|
|
@@ -55,48 +54,46 @@ function useIconSetInfo({ prefix }) {
|
|
|
55
54
|
return reactQuery.useQuery({
|
|
56
55
|
queryKey: ["iconSetInfo", prefix],
|
|
57
56
|
queryFn: async ({ signal }) => {
|
|
58
|
-
var _a;
|
|
59
57
|
if (!prefix) return null;
|
|
60
58
|
const url = new URL("/collection", BASE_API_URL);
|
|
61
|
-
url.searchParams.append("prefix", prefix), url.searchParams.append("info", "true");
|
|
62
|
-
const result = await fetchJson({ url, signal });
|
|
63
|
-
return (_a = result == null ? void 0 : result.info) != null ? _a : null;
|
|
59
|
+
return url.searchParams.append("prefix", prefix), url.searchParams.append("info", "true"), (await fetchJson({ url, signal }))?.info ?? null;
|
|
64
60
|
},
|
|
65
61
|
staleTime: 1 / 0
|
|
66
62
|
});
|
|
67
63
|
}
|
|
68
|
-
|
|
64
|
+
styled__default.default(ui.Grid)`
|
|
69
65
|
grid-template-columns: 1fr min-content;
|
|
70
66
|
position: relative;
|
|
71
|
-
|
|
67
|
+
`;
|
|
68
|
+
const OptionsWrapper = styled__default.default(ui.Box)`
|
|
72
69
|
box-sizing: border-box;
|
|
73
70
|
padding: 0.5rem;
|
|
74
71
|
|
|
75
72
|
& [role='listbox'] {
|
|
76
|
-
display:
|
|
77
|
-
|
|
73
|
+
display: flex;
|
|
74
|
+
flex-wrap: wrap;
|
|
78
75
|
gap: 0.5rem;
|
|
79
76
|
margin: 0;
|
|
80
77
|
padding: 0;
|
|
81
78
|
list-style: none;
|
|
82
|
-
|
|
83
|
-
@media (min-width: 650px) {
|
|
84
|
-
grid-template-columns: repeat(10, minmax(min(100%, 2.5rem), 1fr));
|
|
85
|
-
}
|
|
86
79
|
}
|
|
87
80
|
|
|
88
81
|
& [role='option'] {
|
|
89
82
|
display: grid;
|
|
90
83
|
place-items: center;
|
|
84
|
+
width: clamp(3rem, 10vw, 4rem);
|
|
91
85
|
|
|
92
86
|
& button {
|
|
93
87
|
cursor: pointer;
|
|
94
|
-
aspect-ratio: 1;
|
|
95
88
|
width: 100%;
|
|
96
89
|
|
|
97
90
|
& > [data-ui='Box'] {
|
|
98
91
|
display: flex;
|
|
99
92
|
}
|
|
93
|
+
|
|
94
|
+
& svg {
|
|
95
|
+
aspect-ratio: 1;
|
|
96
|
+
}
|
|
100
97
|
}
|
|
101
98
|
}
|
|
102
99
|
`;
|
|
@@ -104,26 +101,38 @@ function MessageWrapper({ children }) {
|
|
|
104
101
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", muted: !0, children }) });
|
|
105
102
|
}
|
|
106
103
|
const SearchInput = react.forwardRef((props, ref) => {
|
|
107
|
-
const {
|
|
104
|
+
const { selectedIcon, suffix, ...rest } = props;
|
|
108
105
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
109
|
-
|
|
106
|
+
ui.TextInput,
|
|
110
107
|
{
|
|
111
|
-
|
|
108
|
+
...rest,
|
|
112
109
|
ref,
|
|
113
110
|
inputMode: "search",
|
|
114
|
-
|
|
115
|
-
onChange,
|
|
116
|
-
icon: selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(react$2.Icon, { icon: selectedIcon }) : null,
|
|
111
|
+
icon: selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { icon: selectedIcon }) : null,
|
|
117
112
|
placeholder: selectedIcon ? "Search and replace selected icon..." : "Search for an icon...",
|
|
118
113
|
suffix
|
|
119
114
|
}
|
|
120
115
|
);
|
|
121
116
|
});
|
|
122
117
|
SearchInput.displayName = "SearchInput";
|
|
123
|
-
|
|
124
|
-
const { state, data } = props;
|
|
125
|
-
return
|
|
126
|
-
|
|
118
|
+
const SearchResults = react.forwardRef((props, ref) => {
|
|
119
|
+
const { state, data, getItemProps, highlightedIndex, ...rest } = props;
|
|
120
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
121
|
+
(() => {
|
|
122
|
+
switch (state) {
|
|
123
|
+
case "initial":
|
|
124
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Search for icons" });
|
|
125
|
+
case "loading":
|
|
126
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Searching..." });
|
|
127
|
+
case "error":
|
|
128
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Something went wrong..." });
|
|
129
|
+
case "empty":
|
|
130
|
+
return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "No icons found" });
|
|
131
|
+
}
|
|
132
|
+
})(),
|
|
133
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { ...rest, ref, style: { opacity: state === "stale" ? 0.5 : 1 }, children: (state === "data" || state === "stale") && data?.map((icon, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { ...getItemProps({ item: icon, index }), children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { padding: 3, mode: "bleed", selected: index === highlightedIndex, children: /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { icon, width: "100%", height: "100%" }) }) }, icon)) })
|
|
134
|
+
] });
|
|
135
|
+
});
|
|
127
136
|
function UnsetButton(props) {
|
|
128
137
|
const { onUnset } = props;
|
|
129
138
|
return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { border: !0, borderLeft: !1, padding: 1, display: "flex", radius: 2, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.TrashIcon, {}), onClick: onUnset, mode: "bleed", fontSize: 1, padding: 2 }) });
|
|
@@ -131,81 +140,85 @@ function UnsetButton(props) {
|
|
|
131
140
|
function IconifyCombobox(props) {
|
|
132
141
|
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
142
|
collections
|
|
134
|
-
}),
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
143
|
+
}), {
|
|
144
|
+
isOpen,
|
|
145
|
+
getMenuProps,
|
|
146
|
+
getInputProps,
|
|
147
|
+
highlightedIndex,
|
|
148
|
+
getItemProps,
|
|
149
|
+
selectItem,
|
|
150
|
+
setInputValue
|
|
151
|
+
} = downshift.useCombobox({
|
|
152
|
+
items: data ?? [],
|
|
153
|
+
inputValue: term,
|
|
154
|
+
onInputValueChange({ inputValue, selectedItem }) {
|
|
155
|
+
inputValue !== selectedItem && setTerm(inputValue);
|
|
140
156
|
},
|
|
141
|
-
|
|
142
|
-
|
|
157
|
+
onSelectedItemChange({ selectedItem }) {
|
|
158
|
+
selectedItem && (pushSelection(selectedItem), setTerm("", !0), setInputValue(""));
|
|
159
|
+
}
|
|
160
|
+
}), handleUnset = react.useCallback(() => {
|
|
161
|
+
pushSelection(""), setTerm("", !0), selectItem("");
|
|
162
|
+
}, []);
|
|
143
163
|
return react.useEffect(() => {
|
|
144
164
|
isError && (console.error("Iconify input error:", error), toast.push({
|
|
145
165
|
id,
|
|
146
166
|
status: "error",
|
|
147
167
|
title: "Iconify input error",
|
|
148
|
-
description: error
|
|
168
|
+
description: error?.message
|
|
149
169
|
}));
|
|
150
|
-
}, [error, id, isError, toast]), /* @__PURE__ */ jsxRuntime.
|
|
170
|
+
}, [error, id, isError, toast]), /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
151
171
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
152
172
|
SearchInput,
|
|
153
173
|
{
|
|
154
|
-
ref: inputRef,
|
|
155
|
-
term,
|
|
174
|
+
...getInputProps({ ref: inputRef }),
|
|
156
175
|
selectedIcon,
|
|
157
|
-
onChange: handleTermChange,
|
|
158
176
|
suffix: selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(UnsetButton, { onUnset: handleUnset }) : null
|
|
159
177
|
}
|
|
160
178
|
),
|
|
161
179
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
162
180
|
ui.Popover,
|
|
163
181
|
{
|
|
164
|
-
open,
|
|
182
|
+
open: !0,
|
|
183
|
+
style: { display: isOpen ? "block" : "none" },
|
|
165
184
|
placement: "bottom",
|
|
166
185
|
arrow: !1,
|
|
167
186
|
matchReferenceWidth: !0,
|
|
168
|
-
portal: !0,
|
|
169
187
|
constrainSize: !0,
|
|
170
188
|
referenceElement: inputRef.current,
|
|
171
189
|
content: /* @__PURE__ */ jsxRuntime.jsx(OptionsWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
172
190
|
SearchResults,
|
|
173
191
|
{
|
|
192
|
+
...getMenuProps(),
|
|
174
193
|
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
|
|
194
|
+
data,
|
|
195
|
+
getItemProps,
|
|
196
|
+
highlightedIndex
|
|
176
197
|
}
|
|
177
198
|
) })
|
|
178
199
|
}
|
|
179
200
|
)
|
|
180
|
-
] })
|
|
201
|
+
] });
|
|
181
202
|
}
|
|
182
203
|
const queryClient = new reactQuery.QueryClient();
|
|
183
204
|
function QueryClientProvider(props) {
|
|
184
205
|
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: props.children });
|
|
185
206
|
}
|
|
186
207
|
function usePrettyIconName(props) {
|
|
187
|
-
var _a, _b;
|
|
188
208
|
const { name } = props, iconMeta = react.useMemo(
|
|
189
|
-
() =>
|
|
190
|
-
var _a2;
|
|
191
|
-
return (_a2 = props.iconMeta) != null ? _a2 : name ? utils.stringToIcon(name) : null;
|
|
192
|
-
},
|
|
209
|
+
() => props.iconMeta ?? (name ? utils.stringToIcon(name) : null),
|
|
193
210
|
[name, props.iconMeta]
|
|
194
|
-
), iconSetInfo = useIconSetInfo({ prefix:
|
|
211
|
+
), iconSetInfo = useIconSetInfo({ prefix: iconMeta?.prefix ?? null });
|
|
195
212
|
return react.useMemo(
|
|
196
|
-
() => {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
} : null;
|
|
202
|
-
},
|
|
203
|
-
[iconMeta, (_b = iconSetInfo.data) == null ? void 0 : _b.name]
|
|
213
|
+
() => iconMeta ? {
|
|
214
|
+
name: changeCase.sentenceCase(iconMeta.name),
|
|
215
|
+
collection: iconSetInfo.data?.name ?? iconMeta.prefix
|
|
216
|
+
} : null,
|
|
217
|
+
[iconMeta, iconSetInfo.data?.name]
|
|
204
218
|
);
|
|
205
219
|
}
|
|
206
220
|
function IconifyInput(props) {
|
|
207
|
-
|
|
208
|
-
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, handleSelect = react.useCallback(
|
|
221
|
+
const { config, value, onChange: pushChange, schemaType } = props, selectedIcon = value?.name ?? null, options = schemaType.options, collections = !!options?.collections?.length && options.collections || !!config?.collections?.length && config.collections || null, showName = options?.showName ?? config?.showName ?? !1, handleSelect = react.useCallback(
|
|
209
222
|
(icon) => {
|
|
210
223
|
pushChange(icon === "" ? sanity.unset() : sanity.set(icon, ["name"]));
|
|
211
224
|
},
|
|
@@ -224,14 +237,13 @@ function IconifyInput(props) {
|
|
|
224
237
|
] }) }) });
|
|
225
238
|
}
|
|
226
239
|
function IconifyNameDisplay(props) {
|
|
227
|
-
var _a;
|
|
228
240
|
const { name } = props, prettyName = usePrettyIconName({ name });
|
|
229
241
|
return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
|
|
230
242
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, muted: !0, children: "Selected:" }),
|
|
231
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, weight: "semibold", children:
|
|
232
|
-
|
|
243
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, weight: "semibold", children: prettyName?.name ?? name }),
|
|
244
|
+
prettyName?.collection && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: 1, muted: !0, style: { fontStyle: "italic" }, children: [
|
|
233
245
|
"by ",
|
|
234
|
-
prettyName
|
|
246
|
+
prettyName?.collection
|
|
235
247
|
] })
|
|
236
248
|
] });
|
|
237
249
|
}
|
|
@@ -240,13 +252,12 @@ function IconifyPreview(props) {
|
|
|
240
252
|
return typeof title == "string" && iconName ? /* @__PURE__ */ jsxRuntime.jsx(QueryClientProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(IconifyPreviewInner, { ...props, iconName: title, iconMeta: iconName }) }) : props.renderDefault(props);
|
|
241
253
|
}
|
|
242
254
|
function IconifyPreviewInner(props) {
|
|
243
|
-
var _a;
|
|
244
255
|
const { iconMeta, iconName, ...previewProps } = props, prettyName = usePrettyIconName({ iconMeta });
|
|
245
256
|
return props.renderDefault({
|
|
246
257
|
...previewProps,
|
|
247
|
-
media: /* @__PURE__ */ jsxRuntime.jsx(react$
|
|
248
|
-
title:
|
|
249
|
-
subtitle: prettyName
|
|
258
|
+
media: /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { icon: iconName }),
|
|
259
|
+
title: prettyName?.name ?? iconName,
|
|
260
|
+
subtitle: prettyName?.collection
|
|
250
261
|
});
|
|
251
262
|
}
|
|
252
263
|
const iconify = sanity.definePlugin((config = {}) => ({
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +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 type { IconifyInfo } from '@iconify/types';\nimport { keepPreviousData, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useState } from 'react';\nimport { useDebounce } from 'use-debounce';\nimport type { 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 type { 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 margin: 0;\n padding: 0;\n list-style: none;\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 cursor: pointer;\n aspect-ratio: 1;\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 { ComboboxInput } from '@headlessui/react';\nimport { Icon } from '@iconify/react';\nimport { TextInput } from '@sanity/ui';\nimport type { ChangeEventHandler } from 'react';\nimport { forwardRef } from 'react';\n\n// ------------ //\n// SEARCH INPUT //\n// ------------ //\n\ninterface SearchInputProps {\n term: string;\n selectedIcon: string | null;\n onChange: ChangeEventHandler<HTMLInputElement>;\n suffix?: React.ReactNode;\n}\n\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>((props, ref) => {\n const { term, selectedIcon, onChange, suffix } = props;\n\n return (\n <ComboboxInput\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 suffix={suffix}\n />\n );\n});\n\nSearchInput.displayName = 'SearchInput';\n","import { ComboboxOption, ComboboxOptions } from '@headlessui/react';\nimport { Icon } from '@iconify/react';\nimport { Button } from '@sanity/ui';\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 <ComboboxOptions style={{ opacity: state === 'stale' ? 0.5 : 1 }}>\n {data!.map((icon) => (\n <ComboboxOption key={icon} value={icon}>\n {({ focus }) => (\n <Button padding={3} mode=\"bleed\" selected={focus}>\n <Icon icon={icon} width=\"100%\" height=\"100%\" />\n </Button>\n )}\n </ComboboxOption>\n ))}\n </ComboboxOptions>\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\" radius={2}>\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 type { ChangeEventHandler } from 'react';\nimport { useCallback, useEffect, useId, useRef } from 'react';\nimport { match } from 'ts-pattern';\nimport { useSearch } from '../lib/api';\nimport { ComboboxWrapper, OptionsWrapper } from './iconify-combobox.styles';\nimport { SearchInput } from './search-input';\nimport type { SearchResultsProps } from './search-result';\nimport { SearchResults } 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 suffix={selectedIcon ? <UnsetButton onUnset={handleUnset} /> : null}\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 </ComboboxWrapper>\n );\n}\n","import {\n QueryClient,\n QueryClientProvider as ReactQueryClientProvider,\n} from '@tanstack/react-query';\nimport type { 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 type { IconifyIconName } from '@iconify/utils';\nimport { stringToIcon } from '@iconify/utils';\nimport { sentenceCase } from 'change-case';\nimport { useMemo } from 'react';\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, Stack, Text, ThemeProvider } from '@sanity/ui';\nimport { buildTheme } from '@sanity/ui/theme';\nimport { useCallback } from 'react';\nimport type { ObjectInputProps } from 'sanity';\nimport { set, unset } from 'sanity';\nimport { IconifyCombobox } from './combobox';\nimport { QueryClientProvider } from './lib/query-client';\nimport type { 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={buildTheme()}>\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 type { IconifyIconName } from '@iconify/utils';\nimport { stringToIcon } from '@iconify/utils';\nimport type { PreviewProps } from 'sanity';\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 type { FieldProps, ObjectInputProps } from 'sanity';\nimport { definePlugin } from 'sanity';\nimport { IconifyInput } from './iconify-input';\nimport { IconifyPreview } from './iconify-preview';\nimport type { 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","ComboboxInput","TextInput","Icon","ComboboxOptions","ComboboxOption","Button","TrashIcon","useId","useToast","useRef","useEffect","Combobox","jsxs","Fragment","Popover","match","QueryClient","ReactQueryClientProvider","useMemo","_a","stringToIcon","_b","sentenceCase","unset","set","ThemeProvider","buildTheme","Stack","Flex","definePlugin"],"mappings":"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"}
|
|
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 type { IconifyInfo } from '@iconify/types';\nimport { keepPreviousData, useQuery, useQueryClient } from '@tanstack/react-query';\nimport { useCallback, useState } from 'react';\nimport { useDebounce } from 'use-debounce';\nimport type { 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 type { 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: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n & [role='option'] {\n display: grid;\n place-items: center;\n width: clamp(3rem, 10vw, 4rem);\n\n & button {\n cursor: pointer;\n width: 100%;\n\n & > [data-ui='Box'] {\n display: flex;\n }\n\n & svg {\n aspect-ratio: 1;\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 { Icon } from '@iconify/react';\nimport { TextInput } from '@sanity/ui';\nimport { forwardRef } from 'react';\n\ninterface SearchInputProps extends React.HTMLAttributes<HTMLInputElement> {\n selectedIcon: string | null;\n suffix?: React.ReactNode;\n}\n\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>((props, ref) => {\n const { selectedIcon, suffix, ...rest } = props;\n\n return (\n <TextInput\n {...rest}\n ref={ref}\n inputMode=\"search\"\n icon={selectedIcon ? <Icon icon={selectedIcon} /> : null}\n placeholder={selectedIcon ? 'Search and replace selected icon...' : 'Search for an icon...'}\n suffix={suffix}\n />\n );\n});\n\nSearchInput.displayName = 'SearchInput';\n","import { Icon } from '@iconify/react';\nimport { Button } from '@sanity/ui';\nimport type { UseComboboxGetItemPropsOptions, UseComboboxGetItemPropsReturnValue } from 'downshift';\nimport { forwardRef } from 'react';\nimport { MessageWrapper } from './iconify-combobox.styles';\n\ntype GetItemProps = (\n options: UseComboboxGetItemPropsOptions<string>,\n) => UseComboboxGetItemPropsReturnValue;\n\nexport interface SearchResultsProps extends React.HTMLAttributes<HTMLUListElement> {\n state: 'initial' | 'loading' | 'error' | 'empty' | 'data' | 'stale';\n data?: string[];\n getItemProps: GetItemProps;\n highlightedIndex: number;\n}\n\nexport const SearchResults = forwardRef<HTMLUListElement, SearchResultsProps>((props, ref) => {\n const { state, data, getItemProps, highlightedIndex, ...rest } = props;\n\n return (\n <>\n {(() => {\n switch (state) {\n case 'initial':\n return <MessageWrapper>Search for icons</MessageWrapper>;\n case 'loading':\n return <MessageWrapper>Searching...</MessageWrapper>;\n case 'error':\n return <MessageWrapper>Something went wrong...</MessageWrapper>;\n case 'empty':\n return <MessageWrapper>No icons found</MessageWrapper>;\n }\n })()}\n\n <ul {...rest} ref={ref} style={{ opacity: state === 'stale' ? 0.5 : 1 }}>\n {(state === 'data' || state === 'stale') &&\n data?.map((icon, index) => (\n <li key={icon} {...getItemProps({ item: icon, index })}>\n <Button padding={3} mode=\"bleed\" selected={index === highlightedIndex}>\n <Icon icon={icon} width=\"100%\" height=\"100%\" />\n </Button>\n </li>\n ))}\n </ul>\n </>\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\" radius={2}>\n <Button icon={<TrashIcon />} onClick={onUnset} mode=\"bleed\" fontSize={1} padding={2} />\n </Card>\n );\n}\n","import { Popover, useToast } from '@sanity/ui';\nimport { useCombobox } from 'downshift';\nimport { useCallback, useEffect, useId, useRef } from 'react';\nimport { match } from 'ts-pattern';\nimport { useSearch } from '../lib/api';\nimport { OptionsWrapper } from './iconify-combobox.styles';\nimport { SearchInput } from './search-input';\nimport type { SearchResultsProps } from './search-result';\nimport { SearchResults } 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 {\n isOpen,\n getMenuProps,\n getInputProps,\n highlightedIndex,\n getItemProps,\n selectItem,\n setInputValue,\n } = useCombobox({\n items: data ?? [],\n inputValue: term,\n onInputValueChange({ inputValue, selectedItem }) {\n if (inputValue !== selectedItem) {\n setTerm(inputValue);\n }\n },\n onSelectedItemChange({ selectedItem }) {\n if (selectedItem) {\n pushSelection(selectedItem);\n setTerm('', true);\n setInputValue('');\n }\n },\n });\n\n const handleUnset = useCallback(() => {\n pushSelection('');\n setTerm('', true);\n selectItem('');\n }, []);\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 <div>\n {/* @ts-expect-error wrong typings */}\n <SearchInput\n {...getInputProps({ ref: inputRef })}\n selectedIcon={selectedIcon}\n suffix={selectedIcon ? <UnsetButton onUnset={handleUnset} /> : null}\n />\n\n <Popover\n open={true}\n style={{ display: isOpen ? 'block' : 'none' }}\n placement=\"bottom\"\n arrow={false}\n matchReferenceWidth\n constrainSize\n referenceElement={inputRef.current}\n content={\n <OptionsWrapper>\n <SearchResults\n {...getMenuProps()}\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 getItemProps={getItemProps}\n highlightedIndex={highlightedIndex}\n />\n </OptionsWrapper>\n }\n />\n </div>\n );\n}\n","import {\n QueryClient,\n QueryClientProvider as ReactQueryClientProvider,\n} from '@tanstack/react-query';\nimport type { 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 type { IconifyIconName } from '@iconify/utils';\nimport { stringToIcon } from '@iconify/utils';\nimport { sentenceCase } from 'change-case';\nimport { useMemo } from 'react';\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, Stack, Text, ThemeProvider } from '@sanity/ui';\nimport { buildTheme } from '@sanity/ui/theme';\nimport { useCallback } from 'react';\nimport type { ObjectInputProps } from 'sanity';\nimport { set, unset } from 'sanity';\nimport { IconifyCombobox } from './combobox';\nimport { QueryClientProvider } from './lib/query-client';\nimport type { IconifyPluginConfig, IconOptions } from './lib/types';\nimport { usePrettyIconName } from './lib/use-pretty-icon-name';\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 handleSelect = useCallback(\n (icon: string) => {\n pushChange(icon === '' ? unset() : set(icon, ['name']));\n },\n [pushChange],\n );\n\n return (\n <QueryClientProvider>\n <ThemeProvider theme={buildTheme()}>\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\nexport function 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 type { IconifyIconName } from '@iconify/utils';\nimport { stringToIcon } from '@iconify/utils';\nimport type { PreviewProps } from 'sanity';\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 type { FieldProps, ObjectInputProps } from 'sanity';\nimport { definePlugin } from 'sanity';\nimport { IconifyInput } from './iconify-input';\nimport { IconifyPreview } from './iconify-preview';\nimport type { 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","TextInput","Icon","jsxs","Fragment","Button","TrashIcon","useId","useToast","useRef","useCombobox","useEffect","Popover","match","QueryClient","ReactQueryClientProvider","useMemo","stringToIcon","sentenceCase","unset","set","ThemeProvider","buildTheme","Stack","Flex","definePlugin"],"mappings":"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"}
|