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/README.md +1 -1
- package/dist/index.cjs +336 -296
- package/dist/index.d.cts +89 -363
- package/dist/index.d.mts +89 -0
- package/dist/index.mjs +369 -0
- package/package.json +71 -49
- package/src/combobox/search-input.tsx +12 -2
- package/src/lib/api.ts +1 -0
- package/src/lib/icon-types.gen.ts +1 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -363
- package/dist/index.js +0 -362
- package/dist/index.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,71 +1,118 @@
|
|
|
1
|
-
"
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var
|
|
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
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
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
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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
|
-
|
|
315
|
-
|
|
316
|
-
|
|
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
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
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
|