sanity-plugin-iconify 3.0.0 → 4.0.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/dist/index.cjs CHANGED
@@ -1,71 +1,118 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var jsxRuntime = require("react/jsx-runtime"), sanity = require("sanity"), ui = require("@sanity/ui"), theme$1 = 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
- function _interopDefaultCompat(e) {
5
- return e && typeof e == "object" && "default" in e ? e : { default: e };
6
- }
7
- var styled__default = /* @__PURE__ */ _interopDefaultCompat(styled);
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let sanity = require("sanity");
25
+ let _sanity_ui = require("@sanity/ui");
26
+ let _sanity_ui_theme = require("@sanity/ui/theme");
27
+ let react = require("react");
28
+ let downshift = require("downshift");
29
+ let ts_pattern = require("ts-pattern");
30
+ let _tanstack_react_query = require("@tanstack/react-query");
31
+ let use_debounce = require("use-debounce");
32
+ let styled_components = require("styled-components");
33
+ styled_components = __toESM(styled_components, 1);
34
+ let _iconify_react = require("@iconify/react");
35
+ let _sanity_icons = require("@sanity/icons");
36
+ let _iconify_utils = require("@iconify/utils");
37
+ let change_case = require("change-case");
38
+ //#region src/lib/api.ts
8
39
  const BASE_API_URL = "https://api.iconify.design";
9
40
  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
- );
41
+ return fetch(url, { signal }).then((response) => {
42
+ if (!response.ok) throw new Error(`Network error: status ${response.status}`);
43
+ return response.json();
44
+ }).then((result) => result, (error) => {
45
+ if (error instanceof Error) throw error;
46
+ else {
47
+ console.error(`Unknown error: ${error}`);
48
+ throw new Error("Something went wrong");
49
+ }
50
+ });
20
51
  }
21
52
  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
- const url = new URL("/search", BASE_API_URL);
31
- url.searchParams.append("query", debouncedTerm), url.searchParams.append("limit", "60"), collections && url.searchParams.append("prefixes", collections.join(","));
32
- const result = debouncedTerm ? await fetchJson({ url, signal }) : null;
33
- return result && Object.entries(result.collections).forEach(([prefix, info]) => {
34
- queryClient2.setQueryData(["iconSetInfo", prefix], info);
35
- }), result?.icons ?? [];
36
- },
37
- enabled: debouncedTerm.length > 0,
38
- placeholderData: reactQuery.keepPreviousData,
39
- staleTime: 300 * 1e3
40
- // 5 minutes
41
- });
42
- return {
43
- term,
44
- setTerm: updateTerm,
45
- debouncedTerm,
46
- isLoading,
47
- isError,
48
- error,
49
- data,
50
- isPreviousData: isPlaceholderData
51
- };
53
+ const queryClient = (0, _tanstack_react_query.useQueryClient)();
54
+ const [term, setTerm] = (0, react.useState)("");
55
+ const [debouncedTerm, setDebouncedTerm] = (0, use_debounce.useDebounce)(term, 500);
56
+ const updateTerm = (0, react.useCallback)((newTerm, updateImmediately = false) => {
57
+ setTerm(newTerm);
58
+ if (updateImmediately) setDebouncedTerm(newTerm);
59
+ }, [setDebouncedTerm]);
60
+ const { isLoading, isError, error, data, isPlaceholderData } = (0, _tanstack_react_query.useQuery)({
61
+ queryKey: [
62
+ "search",
63
+ collections,
64
+ debouncedTerm
65
+ ],
66
+ queryFn: async ({ signal }) => {
67
+ const url = new URL(`/search`, BASE_API_URL);
68
+ url.searchParams.append("query", debouncedTerm);
69
+ url.searchParams.append("limit", "60");
70
+ if (collections) url.searchParams.append("prefixes", collections.join(","));
71
+ const result = debouncedTerm ? await fetchJson({
72
+ url,
73
+ signal
74
+ }) : null;
75
+ if (result) Object.entries(result.collections).forEach(([prefix, info]) => {
76
+ queryClient.setQueryData(["iconSetInfo", prefix], info);
77
+ });
78
+ return result?.icons ?? [];
79
+ },
80
+ enabled: debouncedTerm.length > 0,
81
+ placeholderData: _tanstack_react_query.keepPreviousData,
82
+ staleTime: 300 * 1e3
83
+ });
84
+ return {
85
+ term,
86
+ setTerm: updateTerm,
87
+ debouncedTerm,
88
+ isLoading,
89
+ isError,
90
+ error,
91
+ data,
92
+ isPreviousData: isPlaceholderData
93
+ };
52
94
  }
53
95
  function useIconSetInfo({ prefix }) {
54
- return reactQuery.useQuery({
55
- queryKey: ["iconSetInfo", prefix],
56
- queryFn: async ({ signal }) => {
57
- if (!prefix) return null;
58
- const url = new URL("/collection", BASE_API_URL);
59
- return url.searchParams.append("prefix", prefix), url.searchParams.append("info", "true"), (await fetchJson({ url, signal }))?.info ?? null;
60
- },
61
- staleTime: 1 / 0
62
- });
96
+ return (0, _tanstack_react_query.useQuery)({
97
+ queryKey: ["iconSetInfo", prefix],
98
+ queryFn: async ({ signal }) => {
99
+ if (!prefix) return null;
100
+ const url = new URL("/collection", BASE_API_URL);
101
+ url.searchParams.append("prefix", prefix);
102
+ url.searchParams.append("info", "true");
103
+ return (await fetchJson({
104
+ url,
105
+ signal
106
+ }))?.info ?? null;
107
+ },
108
+ staleTime: Infinity
109
+ });
63
110
  }
64
- styled__default.default(ui.Grid)`
111
+ (0, styled_components.default)(_sanity_ui.Grid)`
65
112
  grid-template-columns: 1fr min-content;
66
113
  position: relative;
67
114
  `;
68
- const OptionsWrapper = styled__default.default(ui.Box)`
115
+ const OptionsWrapper = (0, styled_components.default)(_sanity_ui.Box)`
69
116
  box-sizing: border-box;
70
117
  padding: 0.5rem;
71
118
 
@@ -98,256 +145,249 @@ const OptionsWrapper = styled__default.default(ui.Box)`
98
145
  }
99
146
  `;
100
147
  function MessageWrapper({ children }) {
101
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", muted: !0, children }) });
148
+ return <_sanity_ui.Card padding={4}>
149
+ <_sanity_ui.Text align="center" muted>
150
+ {children}
151
+ </_sanity_ui.Text>
152
+ </_sanity_ui.Card>;
102
153
  }
103
- const SearchInput = react.memo(
104
- react.forwardRef((props, ref) => {
105
- const { selectedIcon, suffix, ...rest } = props;
106
- return /* @__PURE__ */ jsxRuntime.jsx(
107
- ui.TextInput,
108
- {
109
- ...rest,
110
- ref,
111
- inputMode: "search",
112
- icon: selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { icon: selectedIcon }) : null,
113
- placeholder: selectedIcon ? "Search and replace selected icon..." : "Search for an icon...",
114
- suffix
115
- }
116
- );
117
- })
118
- );
154
+ //#endregion
155
+ //#region src/combobox/search-input.tsx
156
+ const SearchInput = (0, react.memo)((0, react.forwardRef)((props, ref) => {
157
+ const { selectedIcon, suffix, onChange, ...rest } = props;
158
+ return <_sanity_ui.TextInput {...rest} onChange={onChange} ref={ref} inputMode="search" icon={selectedIcon ? <_iconify_react.Icon icon={selectedIcon} /> : null} placeholder={selectedIcon ? "Search and replace selected icon..." : "Search for an icon..."} suffix={suffix} />;
159
+ }));
119
160
  SearchInput.displayName = "SearchInput";
120
- const SearchResults = react.memo(
121
- react.forwardRef((props, ref) => {
122
- const { state, data, getItemProps, highlightedIndex, ...rest } = props;
123
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
124
- (() => {
125
- switch (state) {
126
- case "initial":
127
- return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Search for icons" });
128
- case "loading":
129
- return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Searching..." });
130
- case "error":
131
- return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "Something went wrong..." });
132
- case "empty":
133
- return /* @__PURE__ */ jsxRuntime.jsx(MessageWrapper, { children: "No icons found" });
134
- }
135
- })(),
136
- /* @__PURE__ */ jsxRuntime.jsx(
137
- "ul",
138
- {
139
- ...rest,
140
- ref,
141
- "data-testid": "iconify-results",
142
- style: { opacity: state === "stale" ? 0.5 : 1 },
143
- 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))
144
- }
145
- )
146
- ] });
147
- })
148
- );
161
+ //#endregion
162
+ //#region src/combobox/search-result.tsx
163
+ const SearchResults = (0, react.memo)((0, react.forwardRef)((props, ref) => {
164
+ const { state, data, getItemProps, highlightedIndex, ...rest } = props;
165
+ return <>
166
+ {(() => {
167
+ switch (state) {
168
+ case "initial": return <MessageWrapper>Search for icons</MessageWrapper>;
169
+ case "loading": return <MessageWrapper>Searching...</MessageWrapper>;
170
+ case "error": return <MessageWrapper>Something went wrong...</MessageWrapper>;
171
+ case "empty": return <MessageWrapper>No icons found</MessageWrapper>;
172
+ }
173
+ })()}
174
+
175
+ <ul {...rest} ref={ref} data-testid="iconify-results" style={{ opacity: state === "stale" ? .5 : 1 }}>
176
+ {(state === "data" || state === "stale") && data?.map((icon, index) => <li key={icon} {...getItemProps({
177
+ item: icon,
178
+ index
179
+ })}>
180
+ <_sanity_ui.Button padding={3} mode="bleed" selected={index === highlightedIndex}>
181
+ <_iconify_react.Icon icon={icon} width="100%" height="100%" />
182
+ </_sanity_ui.Button>
183
+ </li>)}
184
+ </ul>
185
+ </>;
186
+ }));
187
+ //#endregion
188
+ //#region src/combobox/unset-button.tsx
149
189
  function UnsetButton(props) {
150
- const { onUnset } = props;
151
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { border: !0, borderLeft: !1, padding: 1, display: "flex", radius: 2, children: /* @__PURE__ */ jsxRuntime.jsx(
152
- ui.Button,
153
- {
154
- "data-testid": "iconify-unset",
155
- icon: /* @__PURE__ */ jsxRuntime.jsx(icons.TrashIcon, {}),
156
- onClick: onUnset,
157
- mode: "bleed",
158
- fontSize: 1,
159
- padding: 2
160
- }
161
- ) });
190
+ const { onUnset } = props;
191
+ return <_sanity_ui.Card border borderLeft={false} padding={1} display="flex" radius={2}>
192
+ <_sanity_ui.Button data-testid="iconify-unset" icon={<_sanity_icons.TrashIcon />} onClick={onUnset} mode="bleed" fontSize={1} padding={2} />
193
+ </_sanity_ui.Card>;
162
194
  }
163
- const IconifyCombobox = react.memo(function(props) {
164
- const {
165
- selectedIcon,
166
- onSelect: pushSelection,
167
- collections,
168
- studioElementProps,
169
- fieldFocused
170
- } = props, id = react.useId(), toast = ui.useToast(), inputRef = react.useRef(null), composedInputRef = react.useCallback(
171
- (node) => {
172
- inputRef.current = node, studioElementProps?.ref && (studioElementProps.ref.current = node);
173
- },
174
- [studioElementProps?.ref]
175
- ), suppressNextBlur = react.useRef(!1), handleFocus = react.useCallback(
176
- (event) => {
177
- suppressNextBlur.current = !0, setTimeout(() => {
178
- suppressNextBlur.current = !1;
179
- }, 0), studioElementProps?.onFocus?.(event);
180
- },
181
- [studioElementProps]
182
- ), handleBlur = react.useCallback(
183
- (event) => {
184
- if (suppressNextBlur.current) {
185
- suppressNextBlur.current = !1;
186
- return;
187
- }
188
- studioElementProps?.onBlur?.(event);
189
- },
190
- [studioElementProps]
191
- ), { term, setTerm, debouncedTerm, isLoading, isError, error, data, isPreviousData } = useSearch({
192
- collections
193
- }), {
194
- isOpen,
195
- getMenuProps,
196
- getInputProps,
197
- highlightedIndex,
198
- getItemProps,
199
- selectItem,
200
- setInputValue,
201
- closeMenu
202
- } = downshift.useCombobox({
203
- items: data ?? [],
204
- inputValue: term,
205
- onInputValueChange({ inputValue, selectedItem }) {
206
- inputValue !== selectedItem && setTerm(inputValue);
207
- },
208
- onSelectedItemChange({ selectedItem }) {
209
- selectedItem && (pushSelection(selectedItem), setTerm("", !0), setInputValue(""));
210
- }
211
- });
212
- react.useEffect(() => {
213
- fieldFocused || closeMenu();
214
- }, [fieldFocused, closeMenu]);
215
- const handleUnset = react.useCallback(() => {
216
- pushSelection(""), setTerm("", !0), selectItem("");
217
- }, [pushSelection, setTerm, selectItem]);
218
- react.useEffect(() => {
219
- isError && (console.error("Iconify input error:", error), toast.push({
220
- id,
221
- status: "error",
222
- title: "Iconify input error",
223
- description: error?.message
224
- }));
225
- }, [error, id, isError, toast]);
226
- const { onBlur: _downshiftOnBlur, ...inputProps } = getInputProps({
227
- ref: composedInputRef,
228
- id: studioElementProps?.id,
229
- "aria-describedby": studioElementProps?.["aria-describedby"],
230
- onFocus: handleFocus
231
- });
232
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
233
- /* @__PURE__ */ jsxRuntime.jsx(
234
- SearchInput,
235
- {
236
- ...inputProps,
237
- onBlur: handleBlur,
238
- selectedIcon,
239
- suffix: selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(UnsetButton, { onUnset: handleUnset }) : null
240
- }
241
- ),
242
- /* @__PURE__ */ jsxRuntime.jsx(
243
- ui.Popover,
244
- {
245
- open: !0,
246
- style: { display: isOpen ? "block" : "none" },
247
- placement: "bottom",
248
- arrow: !1,
249
- matchReferenceWidth: !0,
250
- constrainSize: !0,
251
- referenceElement: inputRef.current,
252
- content: /* @__PURE__ */ jsxRuntime.jsx(OptionsWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(
253
- SearchResults,
254
- {
255
- ...getMenuProps(),
256
- 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"),
257
- data,
258
- getItemProps,
259
- highlightedIndex
260
- }
261
- ) })
262
- }
263
- )
264
- ] });
265
- }), queryClient = new reactQuery.QueryClient();
195
+ //#endregion
196
+ //#region src/combobox/iconify-combobox.tsx
197
+ const IconifyCombobox = (0, react.memo)(function IconifyCombobox(props) {
198
+ const { selectedIcon, onSelect: pushSelection, collections, studioElementProps, fieldFocused } = props;
199
+ const id = (0, react.useId)();
200
+ const toast = (0, _sanity_ui.useToast)();
201
+ const inputRef = (0, react.useRef)(null);
202
+ const composedInputRef = (0, react.useCallback)((node) => {
203
+ inputRef.current = node;
204
+ if (studioElementProps?.ref) studioElementProps.ref.current = node;
205
+ }, [studioElementProps?.ref]);
206
+ const suppressNextBlur = (0, react.useRef)(false);
207
+ const handleFocus = (0, react.useCallback)((event) => {
208
+ suppressNextBlur.current = true;
209
+ setTimeout(() => {
210
+ suppressNextBlur.current = false;
211
+ }, 0);
212
+ studioElementProps?.onFocus?.(event);
213
+ }, [studioElementProps]);
214
+ const handleBlur = (0, react.useCallback)((event) => {
215
+ if (suppressNextBlur.current) {
216
+ suppressNextBlur.current = false;
217
+ return;
218
+ }
219
+ studioElementProps?.onBlur?.(event);
220
+ }, [studioElementProps]);
221
+ const { term, setTerm, debouncedTerm, isLoading, isError, error, data, isPreviousData } = useSearch({ collections });
222
+ const { isOpen, getMenuProps, getInputProps, highlightedIndex, getItemProps, selectItem, setInputValue, closeMenu } = (0, downshift.useCombobox)({
223
+ items: data ?? [],
224
+ inputValue: term,
225
+ onInputValueChange({ inputValue, selectedItem }) {
226
+ if (inputValue !== selectedItem) setTerm(inputValue);
227
+ },
228
+ onSelectedItemChange({ selectedItem }) {
229
+ if (selectedItem) {
230
+ pushSelection(selectedItem);
231
+ setTerm("", true);
232
+ setInputValue("");
233
+ }
234
+ }
235
+ });
236
+ (0, react.useEffect)(() => {
237
+ if (!fieldFocused) closeMenu();
238
+ }, [fieldFocused, closeMenu]);
239
+ const handleUnset = (0, react.useCallback)(() => {
240
+ pushSelection("");
241
+ setTerm("", true);
242
+ selectItem("");
243
+ }, [
244
+ pushSelection,
245
+ setTerm,
246
+ selectItem
247
+ ]);
248
+ (0, react.useEffect)(() => {
249
+ if (isError) {
250
+ console.error("Iconify input error:", error);
251
+ toast.push({
252
+ id,
253
+ status: "error",
254
+ title: "Iconify input error",
255
+ description: error?.message
256
+ });
257
+ }
258
+ }, [
259
+ error,
260
+ id,
261
+ isError,
262
+ toast
263
+ ]);
264
+ const { onBlur: _downshiftOnBlur, ...inputProps } = getInputProps({
265
+ ref: composedInputRef,
266
+ id: studioElementProps?.id,
267
+ "aria-describedby": studioElementProps?.["aria-describedby"],
268
+ onFocus: handleFocus
269
+ });
270
+ return <div>
271
+ <SearchInput {...inputProps} onBlur={handleBlur} selectedIcon={selectedIcon} suffix={selectedIcon ? <UnsetButton onUnset={handleUnset} /> : null} />
272
+
273
+ <_sanity_ui.Popover open={true} style={{ display: isOpen ? "block" : "none" }} placement="bottom" arrow={false} matchReferenceWidth constrainSize referenceElement={inputRef.current} content={<OptionsWrapper>
274
+ <SearchResults {...getMenuProps()} state={(0, ts_pattern.match)(true).returnType().with(isLoading, () => "loading").with(!debouncedTerm, () => "initial").with(isError, () => "error").with(!data || data.length === 0, () => "empty").with(isPreviousData, () => "stale").otherwise(() => "data")} data={data} getItemProps={getItemProps} highlightedIndex={highlightedIndex} />
275
+ </OptionsWrapper>} />
276
+ </div>;
277
+ });
278
+ //#endregion
279
+ //#region src/lib/query-client.tsx
280
+ const queryClient = new _tanstack_react_query.QueryClient();
266
281
  function QueryClientProvider(props) {
267
- return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: props.children });
282
+ return <_tanstack_react_query.QueryClientProvider client={queryClient}>{props.children}</_tanstack_react_query.QueryClientProvider>;
268
283
  }
284
+ //#endregion
285
+ //#region src/lib/use-pretty-icon-name.ts
269
286
  function usePrettyIconName(props) {
270
- const { name } = props, iconMeta = react.useMemo(
271
- () => props.iconMeta ?? (name ? utils.stringToIcon(name) : null),
272
- [name, props.iconMeta]
273
- ), iconSetInfo = useIconSetInfo({ prefix: iconMeta?.prefix ?? null });
274
- return react.useMemo(
275
- () => iconMeta ? {
276
- name: changeCase.sentenceCase(iconMeta.name),
277
- collection: iconSetInfo.data?.name ?? iconMeta.prefix
278
- } : null,
279
- [iconMeta, iconSetInfo.data?.name]
280
- );
287
+ const { name } = props;
288
+ const iconMeta = (0, react.useMemo)(() => props.iconMeta ?? (name ? (0, _iconify_utils.stringToIcon)(name) : null), [name, props.iconMeta]);
289
+ const iconSetInfo = useIconSetInfo({ prefix: iconMeta?.prefix ?? null });
290
+ return (0, react.useMemo)(() => iconMeta ? {
291
+ name: (0, change_case.sentenceCase)(iconMeta.name),
292
+ collection: iconSetInfo.data?.name ?? iconMeta.prefix
293
+ } : null, [iconMeta, iconSetInfo.data?.name]);
281
294
  }
282
- const theme = theme$1.buildTheme(), IconifyInput = react.memo(function(props) {
283
- const { config, value, onChange: pushChange, schemaType, elementProps, focused } = 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(
284
- (icon) => {
285
- pushChange(icon === "" ? sanity.unset() : sanity.set(icon, ["name"]));
286
- },
287
- [pushChange]
288
- );
289
- return /* @__PURE__ */ jsxRuntime.jsx(QueryClientProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.ThemeProvider, { theme, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, children: [
290
- /* @__PURE__ */ jsxRuntime.jsx(
291
- IconifyCombobox,
292
- {
293
- selectedIcon,
294
- onSelect: handleSelect,
295
- collections,
296
- studioElementProps: elementProps,
297
- fieldFocused: focused
298
- }
299
- ),
300
- showName && selectedIcon ? /* @__PURE__ */ jsxRuntime.jsx(IconifyNameDisplay, { name: selectedIcon }) : null
301
- ] }) }) });
295
+ //#endregion
296
+ //#region src/iconify-input.tsx
297
+ const theme = (0, _sanity_ui_theme.buildTheme)();
298
+ const IconifyInput = (0, react.memo)(function IconifyInput(props) {
299
+ const { config, value, onChange: pushChange, schemaType, elementProps, focused } = props;
300
+ const selectedIcon = value?.name ?? null;
301
+ const options = schemaType.options;
302
+ const collections = !!options?.collections?.length && options.collections || !!config?.collections?.length && config.collections || null;
303
+ const showName = options?.showName ?? config?.showName ?? false;
304
+ const handleSelect = (0, react.useCallback)((icon) => {
305
+ pushChange(icon === "" ? (0, sanity.unset)() : (0, sanity.set)(icon, ["name"]));
306
+ }, [pushChange]);
307
+ return <QueryClientProvider>
308
+ <_sanity_ui.ThemeProvider theme={theme}>
309
+ <_sanity_ui.Stack space={2}>
310
+ <IconifyCombobox selectedIcon={selectedIcon} onSelect={handleSelect} collections={collections} studioElementProps={elementProps} fieldFocused={focused} />
311
+
312
+ {showName && selectedIcon ? <IconifyNameDisplay name={selectedIcon} /> : null}
313
+ </_sanity_ui.Stack>
314
+ </_sanity_ui.ThemeProvider>
315
+ </QueryClientProvider>;
302
316
  });
303
317
  function IconifyNameDisplay(props) {
304
- const { name } = props, prettyName = usePrettyIconName({ name });
305
- return /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { gap: 1, children: [
306
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, muted: !0, children: "Selected:" }),
307
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, weight: "semibold", children: prettyName?.name ?? name }),
308
- prettyName?.collection && /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { size: 1, muted: !0, style: { fontStyle: "italic" }, children: [
309
- "by ",
310
- prettyName?.collection
311
- ] })
312
- ] });
318
+ const { name } = props;
319
+ const prettyName = usePrettyIconName({ name });
320
+ return <_sanity_ui.Flex gap={1}>
321
+ <_sanity_ui.Text size={1} muted>
322
+ Selected:
323
+ </_sanity_ui.Text>
324
+
325
+ <_sanity_ui.Text size={1} weight="semibold">
326
+ {prettyName?.name ?? name}
327
+ </_sanity_ui.Text>
328
+
329
+ {prettyName?.collection && <_sanity_ui.Text size={1} muted style={{ fontStyle: "italic" }}>
330
+ by {prettyName?.collection}
331
+ </_sanity_ui.Text>}
332
+ </_sanity_ui.Flex>;
313
333
  }
314
- const IconifyPreview = react.memo(function(props) {
315
- const { title } = props, iconName = typeof props.title == "string" ? utils.stringToIcon(props.title) : null;
316
- return typeof title == "string" && iconName ? /* @__PURE__ */ jsxRuntime.jsx(QueryClientProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(IconifyPreviewInner, { ...props, iconName: title, iconMeta: iconName }) }) : props.renderDefault(props);
334
+ //#endregion
335
+ //#region src/iconify-preview.tsx
336
+ const IconifyPreview = (0, react.memo)(function IconifyPreview(props) {
337
+ const { title } = props;
338
+ const iconName = typeof props.title === "string" ? (0, _iconify_utils.stringToIcon)(props.title) : null;
339
+ if (typeof title === "string" && iconName) return <QueryClientProvider>
340
+ <IconifyPreviewInner {...props} iconName={title} iconMeta={iconName} />
341
+ </QueryClientProvider>;
342
+ return props.renderDefault(props);
317
343
  });
318
344
  function IconifyPreviewInner(props) {
319
- const { iconMeta, iconName, ...previewProps } = props, prettyName = usePrettyIconName({ iconMeta });
320
- return props.renderDefault({
321
- ...previewProps,
322
- media: /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { icon: iconName }),
323
- title: prettyName?.name ?? iconName,
324
- subtitle: prettyName?.collection
325
- });
345
+ const { iconMeta, iconName, ...previewProps } = props;
346
+ const prettyName = usePrettyIconName({ iconMeta });
347
+ return props.renderDefault({
348
+ ...previewProps,
349
+ media: <_iconify_react.Icon icon={iconName} />,
350
+ title: prettyName?.name ?? iconName,
351
+ subtitle: prettyName?.collection
352
+ });
326
353
  }
327
- const iconify = sanity.definePlugin((config = {}) => ({
328
- name: "sanity-plugin-iconify",
329
- schema: {
330
- types: [
331
- {
332
- name: "icon",
333
- title: "Icon",
334
- type: "object",
335
- fields: [
336
- {
337
- name: "name",
338
- title: "Name",
339
- type: "string"
340
- }
341
- ],
342
- components: {
343
- input: (props) => /* @__PURE__ */ jsxRuntime.jsx(IconifyInput, { ...props, config }),
344
- preview: IconifyPreview,
345
- // This makes sure the input component is not indented
346
- field: (props) => props.renderDefault({ ...props, level: 0 })
347
- }
348
- }
349
- ]
350
- }
351
- }));
354
+ //#endregion
355
+ //#region src/iconify-plugin.tsx
356
+ /**
357
+ * Usage in `sanity.config.ts` (or .js)
358
+ *
359
+ * ```ts
360
+ * import { defineConfig } from 'sanity'
361
+ * import { iconify } from 'sanity-plugin-iconify'
362
+ *
363
+ * export default defineConfig({
364
+ * // ...
365
+ * plugins: [iconify()],
366
+ * })
367
+ * ```
368
+ */
369
+ const iconify = (0, sanity.definePlugin)((config = {}) => {
370
+ return {
371
+ name: "sanity-plugin-iconify",
372
+ schema: { types: [{
373
+ name: "icon",
374
+ title: "Icon",
375
+ type: "object",
376
+ fields: [{
377
+ name: "name",
378
+ title: "Name",
379
+ type: "string"
380
+ }],
381
+ components: {
382
+ input: (props) => <IconifyInput {...props} config={config} />,
383
+ preview: IconifyPreview,
384
+ field: (props) => props.renderDefault({
385
+ ...props,
386
+ level: 0
387
+ })
388
+ }
389
+ }] }
390
+ };
391
+ });
392
+ //#endregion
352
393
  exports.iconify = iconify;
353
- //# sourceMappingURL=index.cjs.map