@driftime/sanity-plugin-icon 0.2.0 → 0.4.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 +341 -113
- package/dist/adapters-Bx_MyEX_.js +633 -0
- package/dist/adapters-Bx_MyEX_.js.map +1 -0
- package/dist/drawing-ByrcBbWB.js +50 -0
- package/dist/drawing-ByrcBbWB.js.map +1 -0
- package/dist/index.d.ts +85 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +746 -443
- package/dist/index.js.map +1 -1
- package/dist/names.d.ts +8 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +0 -0
- package/dist/next-loader.d.ts +64 -0
- package/dist/next-loader.d.ts.map +1 -0
- package/dist/next-loader.js +102 -0
- package/dist/next-loader.js.map +1 -0
- package/dist/next.d.ts +43 -0
- package/dist/next.d.ts.map +1 -0
- package/dist/next.js +51 -0
- package/dist/next.js.map +1 -0
- package/dist/nodes-DAzj56Xn.js +139 -0
- package/dist/nodes-DAzj56Xn.js.map +1 -0
- package/dist/read-worker.d.ts +1 -0
- package/dist/read-worker.js +23 -0
- package/dist/read-worker.js.map +1 -0
- package/dist/registry-BEEpqK3z.js +13 -0
- package/dist/registry-BEEpqK3z.js.map +1 -0
- package/dist/registry-dxVzo7ZX.js +58 -0
- package/dist/registry-dxVzo7ZX.js.map +1 -0
- package/dist/render.d.ts +8 -9
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +5 -6
- package/dist/render.js.map +1 -1
- package/dist/sets-DVh8eYeP.js +258 -0
- package/dist/sets-DVh8eYeP.js.map +1 -0
- package/dist/sets-kepuObH8.js +90 -0
- package/dist/sets-kepuObH8.js.map +1 -0
- package/dist/sets.d.ts +50 -0
- package/dist/sets.d.ts.map +1 -0
- package/dist/sets.js +14 -0
- package/dist/sets.js.map +1 -0
- package/dist/types-qlHEYDoN.d.ts +20 -0
- package/dist/types-qlHEYDoN.d.ts.map +1 -0
- package/dist/utils-COPacfAq.js +48 -0
- package/dist/utils-COPacfAq.js.map +1 -0
- package/dist/vite-ifICG8y9.d.ts +98 -0
- package/dist/vite-ifICG8y9.d.ts.map +1 -0
- package/dist/vite.d.ts +2 -0
- package/dist/vite.js +88 -0
- package/dist/vite.js.map +1 -0
- package/package.json +58 -30
- package/LICENSE +0 -21
- package/dist/drawing-Bo0HTICv.js +0 -120
- package/dist/drawing-Bo0HTICv.js.map +0 -1
- package/dist/types-_D2jGm25.d.ts +0 -16
- package/dist/types-_D2jGm25.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,49 +1,148 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { r as pluginName, t as parseIconSet } from "./sets-kepuObH8.js";
|
|
2
|
+
import { n as isDefined, t as convertCase } from "./utils-COPacfAq.js";
|
|
3
|
+
import { a as resolveIconDrawing, o as serializeIconDrawing } from "./nodes-DAzj56Xn.js";
|
|
4
|
+
import { t as Drawing } from "./drawing-ByrcBbWB.js";
|
|
5
|
+
import { t as getIconSetKey } from "./registry-BEEpqK3z.js";
|
|
6
|
+
import { ChangeIndicator, FieldActionsProvider, FieldActionsResolver, FormField, defineField, definePlugin, defineType, getPublishedId, set, setIfMissing, unset, useFormValue } from "sanity";
|
|
3
7
|
import { c } from "react/compiler-runtime";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { CloseIcon } from "@sanity/icons/Close";
|
|
6
|
-
import { Box, Button, Dialog, Flex, Grid, Spinner, Stack, Text, TextInput } from "@sanity/ui";
|
|
7
8
|
import { createElement, useEffect, useRef, useState } from "react";
|
|
9
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
10
|
+
import { CloseIcon } from "@sanity/icons/Close";
|
|
11
|
+
import { Box, Button, Card, Dialog, Flex, Grid, Spinner, Stack, Text, TextInput } from "@sanity/ui";
|
|
8
12
|
import { SearchIcon } from "@sanity/icons/Search";
|
|
13
|
+
import { WarningOutlineIcon } from "@sanity/icons/WarningOutline";
|
|
9
14
|
import { Popover } from "@sanity/ui/popover";
|
|
15
|
+
import { iconRegistry } from "@driftime/sanity-plugin-icon/sets";
|
|
16
|
+
/**
|
|
17
|
+
* Checks whether a form node has members, as objects and arrays of objects do.
|
|
18
|
+
*
|
|
19
|
+
* @param node - The form node to check.
|
|
20
|
+
* @returns True if the node has members.
|
|
21
|
+
*/
|
|
22
|
+
function hasMembers(node) {
|
|
23
|
+
return "members" in node;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Collects the validation on a form node and everything inside it.
|
|
27
|
+
*
|
|
28
|
+
* @param node - The form node.
|
|
29
|
+
* @returns Every validation result on the node or inside it.
|
|
30
|
+
*/
|
|
31
|
+
function collectNodeValidation(node) {
|
|
32
|
+
return [...node.validation, ...hasMembers(node) ? collectMemberValidation(node.members) : []];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Collects the validation anywhere inside a field's members. The form only passes a field the
|
|
36
|
+
* validation at its own path, so a field that hides its members would otherwise show none of theirs.
|
|
37
|
+
*
|
|
38
|
+
* @param members - The members.
|
|
39
|
+
* @returns Every validation result on the members or inside them.
|
|
40
|
+
*/
|
|
41
|
+
function collectMemberValidation(members) {
|
|
42
|
+
return members.flatMap((member) => member.kind === "field" ? collectNodeValidation(member.field) : member.kind === "fieldSet" ? collectMemberValidation(member.fieldSet.members) : member.kind === "item" ? collectNodeValidation(member.item) : []);
|
|
43
|
+
}
|
|
10
44
|
function Field(t0) {
|
|
11
|
-
let $ = c(
|
|
12
|
-
|
|
13
|
-
|
|
45
|
+
let $ = c(40), { actions, schemaType, title, description, presence, validation, level, inputId, path, changed, children, inputProps } = t0, t1;
|
|
46
|
+
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = [], $[0] = t1) : t1 = $[0];
|
|
47
|
+
let [headerActions, setHeaderActions] = useState(t1), t2;
|
|
48
|
+
$[1] === Symbol.for("react.memo_cache_sentinel") ? (t2 = ["_id"], $[1] = t2) : t2 = $[1];
|
|
49
|
+
let documentId = useFormValue(t2), fieldValidation, focused, t3;
|
|
50
|
+
if ($[2] !== actions || $[3] !== documentId || $[4] !== inputProps.focused || $[5] !== inputProps.members || $[6] !== path || $[7] !== schemaType || $[8] !== validation) {
|
|
51
|
+
let publishedId = typeof documentId == "string" ? getPublishedId(documentId) : void 0;
|
|
52
|
+
focused = inputProps.focused === !0;
|
|
53
|
+
let t4;
|
|
54
|
+
$[12] !== inputProps.members || $[13] !== validation ? (t4 = [...validation, ...collectMemberValidation(inputProps.members)], $[12] = inputProps.members, $[13] = validation, $[14] = t4) : t4 = $[14], fieldValidation = t4, t3 = isDefined(publishedId) && isDefined(actions) && /* @__PURE__ */ jsx(FieldActionsResolver, {
|
|
55
|
+
actions,
|
|
56
|
+
documentId: publishedId,
|
|
57
|
+
documentType: schemaType.name,
|
|
58
|
+
onActions: setHeaderActions,
|
|
59
|
+
path,
|
|
60
|
+
schemaType
|
|
61
|
+
}), $[2] = actions, $[3] = documentId, $[4] = inputProps.focused, $[5] = inputProps.members, $[6] = path, $[7] = schemaType, $[8] = validation, $[9] = fieldValidation, $[10] = focused, $[11] = t3;
|
|
62
|
+
} else fieldValidation = $[9], focused = $[10], t3 = $[11];
|
|
63
|
+
let t4;
|
|
64
|
+
$[15] !== changed || $[16] !== children || $[17] !== focused || $[18] !== path ? (t4 = /* @__PURE__ */ jsx(ChangeIndicator, {
|
|
65
|
+
path,
|
|
66
|
+
hasFocus: focused,
|
|
67
|
+
isChanged: changed,
|
|
68
|
+
children
|
|
69
|
+
}), $[15] = changed, $[16] = children, $[17] = focused, $[18] = path, $[19] = t4) : t4 = $[19];
|
|
70
|
+
let t5;
|
|
71
|
+
$[20] !== description || $[21] !== fieldValidation || $[22] !== headerActions || $[23] !== inputId || $[24] !== inputProps.readOnly || $[25] !== level || $[26] !== path || $[27] !== presence || $[28] !== schemaType.deprecated || $[29] !== t4 || $[30] !== title ? (t5 = /* @__PURE__ */ jsx(FormField, {
|
|
72
|
+
__unstable_headerActions: headerActions,
|
|
73
|
+
__unstable_presence: presence,
|
|
14
74
|
description,
|
|
15
75
|
inputId,
|
|
16
|
-
|
|
76
|
+
level,
|
|
77
|
+
title,
|
|
78
|
+
validation: fieldValidation,
|
|
79
|
+
deprecated: schemaType.deprecated,
|
|
17
80
|
path,
|
|
18
|
-
|
|
19
|
-
|
|
81
|
+
readOnly: inputProps.readOnly,
|
|
82
|
+
children: t4
|
|
83
|
+
}), $[20] = description, $[21] = fieldValidation, $[22] = headerActions, $[23] = inputId, $[24] = inputProps.readOnly, $[25] = level, $[26] = path, $[27] = presence, $[28] = schemaType.deprecated, $[29] = t4, $[30] = title, $[31] = t5) : t5 = $[31];
|
|
84
|
+
let t6;
|
|
85
|
+
$[32] !== focused || $[33] !== headerActions || $[34] !== path || $[35] !== t5 ? (t6 = /* @__PURE__ */ jsx(FieldActionsProvider, {
|
|
86
|
+
actions: headerActions,
|
|
87
|
+
focused,
|
|
88
|
+
path,
|
|
89
|
+
children: t5
|
|
90
|
+
}), $[32] = focused, $[33] = headerActions, $[34] = path, $[35] = t5, $[36] = t6) : t6 = $[36];
|
|
91
|
+
let t7;
|
|
92
|
+
return $[37] !== t3 || $[38] !== t6 ? (t7 = /* @__PURE__ */ jsxs(Fragment, { children: [t3, t6] }), $[37] = t3, $[38] = t6, $[39] = t7) : t7 = $[39], t7;
|
|
93
|
+
}
|
|
94
|
+
/** Default props for the plugin's own icons. Icons from `@sanity/icons` already match the Studio. */
|
|
95
|
+
const defaultIconProps = {
|
|
96
|
+
width: "1em",
|
|
97
|
+
height: "1em",
|
|
98
|
+
strokeWidth: 1.5
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Wraps an SVG icon component for use in the Studio.
|
|
102
|
+
*
|
|
103
|
+
* @param icon - The icon to wrap.
|
|
104
|
+
* @param props - Props that override the Studio icon defaults.
|
|
105
|
+
* @returns An icon component.
|
|
106
|
+
*/
|
|
107
|
+
function createSanityIcon(icon, props) {
|
|
108
|
+
let Icon = icon;
|
|
109
|
+
function SanityIcon() {
|
|
110
|
+
return createElement(Icon, {
|
|
111
|
+
...defaultIconProps,
|
|
112
|
+
...props
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return SanityIcon;
|
|
20
116
|
}
|
|
21
|
-
/**
|
|
117
|
+
/** Gap between rows in pixels. */
|
|
22
118
|
const gridLayoutStyle = {
|
|
23
119
|
justifyItems: "center",
|
|
24
120
|
rowGap: 4
|
|
25
121
|
};
|
|
26
122
|
function Cell(t0) {
|
|
27
|
-
let $ = c(
|
|
28
|
-
$[0] === t0 ? (focusable = $[1], icon = $[2],
|
|
123
|
+
let $ = c(28), focusable, icon, onHover, onSelect, position, props, selected, total;
|
|
124
|
+
$[0] === t0 ? (focusable = $[1], icon = $[2], onHover = $[3], onSelect = $[4], position = $[5], props = $[6], selected = $[7], total = $[8]) : ({icon, selected, focusable, position, total, onSelect, onHover, ...props} = t0, $[0] = t0, $[1] = focusable, $[2] = icon, $[3] = onHover, $[4] = onSelect, $[5] = position, $[6] = props, $[7] = selected, $[8] = total);
|
|
29
125
|
let t1 = focusable ? 0 : -1, t2;
|
|
30
|
-
$[
|
|
126
|
+
$[9] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
|
|
31
127
|
width: 40,
|
|
32
128
|
height: 40
|
|
33
|
-
}, $[
|
|
129
|
+
}, $[9] = t2) : t2 = $[9];
|
|
34
130
|
let t3;
|
|
35
|
-
$[
|
|
36
|
-
|
|
131
|
+
$[10] === icon.drawing ? t3 = $[11] : (t3 = /* @__PURE__ */ jsx(Drawing, {
|
|
132
|
+
drawing: icon.drawing,
|
|
37
133
|
width: "1.25em",
|
|
38
|
-
height: "1.25em"
|
|
39
|
-
|
|
40
|
-
}), $[9] = icon.node, $[10] = t3);
|
|
134
|
+
height: "1.25em"
|
|
135
|
+
}), $[10] = icon.drawing, $[11] = t3);
|
|
41
136
|
let t4;
|
|
42
|
-
$[
|
|
137
|
+
$[12] !== icon || $[13] !== onSelect ? (t4 = () => {
|
|
43
138
|
onSelect(icon);
|
|
44
|
-
}, $[
|
|
139
|
+
}, $[12] = icon, $[13] = onSelect, $[14] = t4) : t4 = $[14];
|
|
45
140
|
let t5;
|
|
46
|
-
|
|
141
|
+
$[15] !== icon || $[16] !== onHover ? (t5 = (event) => {
|
|
142
|
+
onHover(icon, event.currentTarget);
|
|
143
|
+
}, $[15] = icon, $[16] = onHover, $[17] = t5) : t5 = $[17];
|
|
144
|
+
let t6;
|
|
145
|
+
return $[18] !== icon.label || $[19] !== position || $[20] !== props || $[21] !== selected || $[22] !== t1 || $[23] !== t3 || $[24] !== t4 || $[25] !== t5 || $[26] !== total ? (t6 = /* @__PURE__ */ jsx(Button, {
|
|
47
146
|
type: "button",
|
|
48
147
|
role: "option",
|
|
49
148
|
"aria-selected": selected,
|
|
@@ -56,83 +155,135 @@ function Cell(t0) {
|
|
|
56
155
|
style: t2,
|
|
57
156
|
icon: t3,
|
|
58
157
|
"aria-label": icon.label,
|
|
59
|
-
"data-icon": icon.name,
|
|
60
158
|
onClick: t4,
|
|
159
|
+
onMouseEnter: t5,
|
|
61
160
|
...props
|
|
62
|
-
}), $[
|
|
161
|
+
}), $[18] = icon.label, $[19] = position, $[20] = props, $[21] = selected, $[22] = t1, $[23] = t3, $[24] = t4, $[25] = t5, $[26] = total, $[27] = t6) : t6 = $[27], t6;
|
|
63
162
|
}
|
|
64
163
|
function Library(t0) {
|
|
65
|
-
let $ = c(
|
|
66
|
-
$[0] === t0 ? (activeCell = $[1], activeIndex = $[2], icons = $[3], onClearSearch = $[4],
|
|
67
|
-
let { totalRows, firstRow, lastRow } = rows, t1;
|
|
68
|
-
if ($[
|
|
69
|
-
let visible = icons.slice(firstRow * 8, lastRow * 8)
|
|
70
|
-
$[
|
|
164
|
+
let $ = c(44), activeCell, activeIndex, icons, onClearSearch, onHover, onSelect, props, rows, search, selected;
|
|
165
|
+
$[0] === t0 ? (activeCell = $[1], activeIndex = $[2], icons = $[3], onClearSearch = $[4], onHover = $[5], onSelect = $[6], props = $[7], rows = $[8], search = $[9], selected = $[10]) : ({icons, rows, selected, activeIndex, activeCell, search, onSelect, onHover, onClearSearch, ...props} = t0, $[0] = t0, $[1] = activeCell, $[2] = activeIndex, $[3] = icons, $[4] = onClearSearch, $[5] = onHover, $[6] = onSelect, $[7] = props, $[8] = rows, $[9] = search, $[10] = selected);
|
|
166
|
+
let { totalRows, firstRow, lastRow } = rows, T0, t1, t2, t3, t4, t5, t6;
|
|
167
|
+
if ($[11] !== activeCell || $[12] !== activeIndex || $[13] !== firstRow || $[14] !== icons || $[15] !== lastRow || $[16] !== onClearSearch || $[17] !== onHover || $[18] !== onSelect || $[19] !== props || $[20] !== search || $[21] !== selected || $[22] !== totalRows) {
|
|
168
|
+
let visible = icons.slice(firstRow * 8, lastRow * 8);
|
|
169
|
+
T0 = Box, t1 = "listbox", t2 = "Icon library", $[30] === icons ? t3 = $[31] : (t3 = isDefined(icons) ? {
|
|
71
170
|
height: 348,
|
|
72
171
|
overflowY: "auto"
|
|
73
|
-
}, $[
|
|
74
|
-
let t3;
|
|
75
|
-
$[23] !== icons.length || $[24] !== onClearSearch || $[25] !== search ? (t3 = icons.length === 0 && /* @__PURE__ */ jsxs(Flex, {
|
|
172
|
+
} : void 0, $[30] = icons, $[31] = t3), t4 = props, $[32] !== icons || $[33] !== onClearSearch || $[34] !== search ? (t5 = !isDefined(icons) && /* @__PURE__ */ jsxs(Flex, {
|
|
76
173
|
align: "center",
|
|
77
174
|
justify: "center",
|
|
78
175
|
direction: "column",
|
|
79
176
|
gap: 3,
|
|
80
|
-
|
|
81
|
-
|
|
177
|
+
paddingTop: 5,
|
|
178
|
+
paddingBottom: 6,
|
|
179
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
82
180
|
size: 1,
|
|
83
181
|
muted: !0,
|
|
84
|
-
children:
|
|
85
|
-
"Nothing matches “",
|
|
86
|
-
search,
|
|
87
|
-
"”."
|
|
88
|
-
]
|
|
182
|
+
children: `Nothing matches "${search}".`
|
|
89
183
|
}), /* @__PURE__ */ jsx(Button, {
|
|
90
184
|
type: "button",
|
|
91
185
|
mode: "ghost",
|
|
92
186
|
text: "Clear search",
|
|
93
187
|
onClick: onClearSearch
|
|
94
188
|
})]
|
|
95
|
-
}), $[
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
189
|
+
}), $[32] = icons, $[33] = onClearSearch, $[34] = search, $[35] = t5) : t5 = $[35], t6 = isDefined(icons) && /* @__PURE__ */ jsx(Grid, {
|
|
190
|
+
gridTemplateColumns: 8,
|
|
191
|
+
style: {
|
|
192
|
+
...gridLayoutStyle,
|
|
193
|
+
paddingTop: firstRow * 44,
|
|
194
|
+
paddingBottom: (totalRows - lastRow) * 44
|
|
195
|
+
},
|
|
196
|
+
children: visible.map((icon, offset) => {
|
|
197
|
+
let index = firstRow * 8 + offset;
|
|
198
|
+
return /* @__PURE__ */ jsx(Cell, {
|
|
199
|
+
ref: index === activeIndex ? activeCell : void 0,
|
|
200
|
+
icon,
|
|
201
|
+
selected: icon.name === selected,
|
|
202
|
+
focusable: index === activeIndex,
|
|
203
|
+
position: index + 1,
|
|
204
|
+
total: icons.length,
|
|
205
|
+
onSelect,
|
|
206
|
+
onHover
|
|
207
|
+
}, icon.name);
|
|
208
|
+
})
|
|
209
|
+
}), $[11] = activeCell, $[12] = activeIndex, $[13] = firstRow, $[14] = icons, $[15] = lastRow, $[16] = onClearSearch, $[17] = onHover, $[18] = onSelect, $[19] = props, $[20] = search, $[21] = selected, $[22] = totalRows, $[23] = T0, $[24] = t1, $[25] = t2, $[26] = t3, $[27] = t4, $[28] = t5, $[29] = t6;
|
|
210
|
+
} else T0 = $[23], t1 = $[24], t2 = $[25], t3 = $[26], t4 = $[27], t5 = $[28], t6 = $[29];
|
|
211
|
+
let t7;
|
|
212
|
+
return $[36] !== T0 || $[37] !== t1 || $[38] !== t2 || $[39] !== t3 || $[40] !== t4 || $[41] !== t5 || $[42] !== t6 ? (t7 = /* @__PURE__ */ jsxs(T0, {
|
|
213
|
+
role: t1,
|
|
214
|
+
"aria-label": t2,
|
|
215
|
+
style: t3,
|
|
216
|
+
...t4,
|
|
217
|
+
children: [t5, t6]
|
|
218
|
+
}), $[36] = T0, $[37] = t1, $[38] = t2, $[39] = t3, $[40] = t4, $[41] = t5, $[42] = t6, $[43] = t7) : t7 = $[43], t7;
|
|
219
|
+
}
|
|
220
|
+
function CodeText(t0) {
|
|
221
|
+
let $ = c(10), props, text;
|
|
222
|
+
$[0] === t0 ? (props = $[1], text = $[2]) : ({text, ...props} = t0, $[0] = t0, $[1] = props, $[2] = text);
|
|
223
|
+
let t1, t2;
|
|
224
|
+
if ($[3] !== props || $[4] !== text) {
|
|
225
|
+
let parts = text.split("`");
|
|
226
|
+
t1 = props, t2 = parts.map((part, index) => {
|
|
227
|
+
let start = parts.slice(0, index).join("`").length;
|
|
228
|
+
return index % 2 == 1 ? /* @__PURE__ */ jsx("code", { children: part }, start) : part;
|
|
229
|
+
}), $[3] = props, $[4] = text, $[5] = t1, $[6] = t2;
|
|
230
|
+
} else t1 = $[5], t2 = $[6];
|
|
231
|
+
let t3;
|
|
232
|
+
return $[7] !== t1 || $[8] !== t2 ? (t3 = /* @__PURE__ */ jsx("span", {
|
|
233
|
+
...t1,
|
|
234
|
+
children: t2
|
|
235
|
+
}), $[7] = t1, $[8] = t2, $[9] = t3) : t3 = $[9], t3;
|
|
236
|
+
}
|
|
237
|
+
function Problem(t0) {
|
|
238
|
+
let $ = c(14), problem, props;
|
|
239
|
+
$[0] === t0 ? (problem = $[1], props = $[2]) : ({problem, ...props} = t0, $[0] = t0, $[1] = problem, $[2] = props);
|
|
240
|
+
let t1;
|
|
241
|
+
$[3] === Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsx(Text, {
|
|
242
|
+
size: 1,
|
|
243
|
+
children: /* @__PURE__ */ jsx(WarningOutlineIcon, {})
|
|
244
|
+
}), $[3] = t1) : t1 = $[3];
|
|
245
|
+
let t2;
|
|
246
|
+
$[4] === problem.title ? t2 = $[5] : (t2 = /* @__PURE__ */ jsx(Text, {
|
|
247
|
+
size: 1,
|
|
248
|
+
weight: "medium",
|
|
249
|
+
children: /* @__PURE__ */ jsx(CodeText, { text: problem.title })
|
|
250
|
+
}), $[4] = problem.title, $[5] = t2);
|
|
251
|
+
let t3;
|
|
252
|
+
$[6] === problem.description ? t3 = $[7] : (t3 = /* @__PURE__ */ jsx(Text, {
|
|
253
|
+
size: 1,
|
|
254
|
+
muted: !0,
|
|
255
|
+
children: /* @__PURE__ */ jsx(CodeText, { text: problem.description })
|
|
256
|
+
}), $[6] = problem.description, $[7] = t3);
|
|
257
|
+
let t4;
|
|
258
|
+
$[8] !== t2 || $[9] !== t3 ? (t4 = /* @__PURE__ */ jsxs(Flex, {
|
|
259
|
+
gap: 3,
|
|
260
|
+
children: [t1, /* @__PURE__ */ jsxs(Stack, {
|
|
261
|
+
gap: 3,
|
|
262
|
+
children: [t2, t3]
|
|
263
|
+
})]
|
|
264
|
+
}), $[8] = t2, $[9] = t3, $[10] = t4) : t4 = $[10];
|
|
265
|
+
let t5;
|
|
266
|
+
return $[11] !== props || $[12] !== t4 ? (t5 = /* @__PURE__ */ jsx(Card, {
|
|
267
|
+
tone: "caution",
|
|
268
|
+
padding: 4,
|
|
269
|
+
radius: 2,
|
|
270
|
+
border: !0,
|
|
271
|
+
...props,
|
|
272
|
+
children: t4
|
|
273
|
+
}), $[11] = props, $[12] = t4, $[13] = t5) : t5 = $[13], t5;
|
|
123
274
|
}
|
|
124
275
|
function Recent(t0) {
|
|
125
|
-
let $ = c(
|
|
126
|
-
$[0] === t0 ? (icons = $[1], onForget = $[2],
|
|
276
|
+
let $ = c(26), icons, onForget, onHover, onSelect, props, selected;
|
|
277
|
+
$[0] === t0 ? (icons = $[1], onForget = $[2], onHover = $[3], onSelect = $[4], props = $[5], selected = $[6]) : ({icons, selected, onSelect, onHover, onForget, ...props} = t0, $[0] = t0, $[1] = icons, $[2] = onForget, $[3] = onHover, $[4] = onSelect, $[5] = props, $[6] = selected);
|
|
127
278
|
let t1;
|
|
128
|
-
$[
|
|
279
|
+
$[7] === Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsx(Text, {
|
|
129
280
|
size: 1,
|
|
130
281
|
weight: "medium",
|
|
131
282
|
muted: !0,
|
|
132
283
|
children: "Recent icons"
|
|
133
|
-
}), $[
|
|
284
|
+
}), $[7] = t1) : t1 = $[7];
|
|
134
285
|
let t2;
|
|
135
|
-
$[
|
|
286
|
+
$[8] === onForget ? t2 = $[9] : (t2 = /* @__PURE__ */ jsxs(Flex, {
|
|
136
287
|
align: "center",
|
|
137
288
|
justify: "space-between",
|
|
138
289
|
gap: 2,
|
|
@@ -143,98 +294,74 @@ function Recent(t0) {
|
|
|
143
294
|
padding: 2,
|
|
144
295
|
text: "Clear",
|
|
145
296
|
onClick: onForget,
|
|
146
|
-
"aria-label": "
|
|
297
|
+
"aria-label": "Clear recent icons"
|
|
147
298
|
})]
|
|
148
|
-
}), $[
|
|
299
|
+
}), $[8] = onForget, $[9] = t2);
|
|
149
300
|
let t3;
|
|
150
|
-
if ($[
|
|
301
|
+
if ($[10] !== icons || $[11] !== onHover || $[12] !== onSelect || $[13] !== selected) {
|
|
151
302
|
let t4;
|
|
152
|
-
$[
|
|
303
|
+
$[15] !== icons.length || $[16] !== onHover || $[17] !== onSelect || $[18] !== selected ? (t4 = (icon, index) => /* @__PURE__ */ jsx(Cell, {
|
|
153
304
|
icon,
|
|
154
305
|
selected: icon.name === selected,
|
|
155
306
|
focusable: !0,
|
|
156
307
|
position: index + 1,
|
|
157
308
|
total: icons.length,
|
|
158
|
-
onSelect
|
|
159
|
-
|
|
160
|
-
|
|
309
|
+
onSelect,
|
|
310
|
+
onHover
|
|
311
|
+
}, icon.name), $[15] = icons.length, $[16] = onHover, $[17] = onSelect, $[18] = selected, $[19] = t4) : t4 = $[19], t3 = icons.map(t4), $[10] = icons, $[11] = onHover, $[12] = onSelect, $[13] = selected, $[14] = t3;
|
|
312
|
+
} else t3 = $[14];
|
|
161
313
|
let t4;
|
|
162
|
-
$[
|
|
314
|
+
$[20] === t3 ? t4 = $[21] : (t4 = /* @__PURE__ */ jsx(Grid, {
|
|
163
315
|
role: "listbox",
|
|
164
316
|
"aria-label": "Recent icons",
|
|
165
317
|
gridTemplateColumns: 8,
|
|
166
318
|
style: gridLayoutStyle,
|
|
167
319
|
children: t3
|
|
168
|
-
}), $[
|
|
320
|
+
}), $[20] = t3, $[21] = t4);
|
|
169
321
|
let t5;
|
|
170
|
-
return $[
|
|
322
|
+
return $[22] !== props || $[23] !== t2 || $[24] !== t4 ? (t5 = /* @__PURE__ */ jsxs(Stack, {
|
|
171
323
|
gap: 3,
|
|
172
324
|
...props,
|
|
173
325
|
children: [t2, t4]
|
|
174
|
-
}), $[
|
|
175
|
-
}
|
|
176
|
-
function Tooltip(t0) {
|
|
177
|
-
let $ = c(14), hovered, props;
|
|
178
|
-
$[0] === t0 ? (hovered = $[1], props = $[2]) : ({hovered, ...props} = t0, $[0] = t0, $[1] = hovered, $[2] = props);
|
|
179
|
-
let t1;
|
|
180
|
-
$[3] === hovered ? t1 = $[4] : (t1 = isDefined(hovered), $[3] = hovered, $[4] = t1);
|
|
181
|
-
let t2 = hovered?.element ?? null, t3, t4;
|
|
182
|
-
$[5] === Symbol.for("react.memo_cache_sentinel") ? (t3 = [
|
|
183
|
-
-4,
|
|
184
|
-
0,
|
|
185
|
-
0,
|
|
186
|
-
0
|
|
187
|
-
], t4 = { pointerEvents: "none" }, $[5] = t3, $[6] = t4) : (t3 = $[5], t4 = $[6]);
|
|
188
|
-
let t5;
|
|
189
|
-
$[7] === hovered ? t5 = $[8] : (t5 = isDefined(hovered) && /* @__PURE__ */ jsxs(Stack, {
|
|
190
|
-
gap: 3,
|
|
191
|
-
style: { maxWidth: "16rem" },
|
|
192
|
-
children: [/* @__PURE__ */ jsx(Text, {
|
|
193
|
-
size: 1,
|
|
194
|
-
weight: "medium",
|
|
195
|
-
children: hovered.icon.label
|
|
196
|
-
}), isDefined(hovered.icon.tags) && /* @__PURE__ */ jsx(Text, {
|
|
197
|
-
size: 1,
|
|
198
|
-
muted: !0,
|
|
199
|
-
children: hovered.icon.tags
|
|
200
|
-
})]
|
|
201
|
-
}), $[7] = hovered, $[8] = t5);
|
|
202
|
-
let t6;
|
|
203
|
-
return $[9] !== props || $[10] !== t1 || $[11] !== t2 || $[12] !== t5 ? (t6 = /* @__PURE__ */ jsx(Popover, {
|
|
204
|
-
open: t1,
|
|
205
|
-
referenceElement: t2,
|
|
206
|
-
placement: "top",
|
|
207
|
-
portal: !0,
|
|
208
|
-
padding: 3,
|
|
209
|
-
__unstable_margins: t3,
|
|
210
|
-
style: t4,
|
|
211
|
-
content: t5,
|
|
212
|
-
...props
|
|
213
|
-
}), $[9] = props, $[10] = t1, $[11] = t2, $[12] = t5, $[13] = t6) : t6 = $[13], t6;
|
|
326
|
+
}), $[22] = props, $[23] = t2, $[24] = t4, $[25] = t5) : t5 = $[25], t5;
|
|
214
327
|
}
|
|
215
|
-
/** Properties every icon the Studio draws is rendered with. */
|
|
216
|
-
const defaultIconProps = {
|
|
217
|
-
width: "1em",
|
|
218
|
-
height: "1em",
|
|
219
|
-
strokeWidth: 1.5
|
|
220
|
-
};
|
|
221
328
|
/**
|
|
222
|
-
*
|
|
223
|
-
* tag are matched the same way.
|
|
329
|
+
* Normalises text for search, so hyphenated names and multi-word keywords match the same way.
|
|
224
330
|
*
|
|
225
|
-
* @param value - The text
|
|
226
|
-
* @returns The text
|
|
331
|
+
* @param value - The text.
|
|
332
|
+
* @returns The normalised text.
|
|
227
333
|
*/
|
|
228
|
-
function
|
|
334
|
+
function normalizeTerms(value) {
|
|
229
335
|
return value.toLowerCase().replaceAll(/[\s-]+/gu, " ").trim();
|
|
230
336
|
}
|
|
231
337
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
338
|
+
* Splits text into the parts a search matches and the parts it doesn't, matching the way search does: ignoring case,
|
|
339
|
+
* and treating spaces and hyphens alike.
|
|
340
|
+
*
|
|
341
|
+
* @param text - The text to split.
|
|
342
|
+
* @param query - The normalised search.
|
|
343
|
+
* @returns The parts in order, each with where it starts in the text and whether it matches.
|
|
344
|
+
*/
|
|
345
|
+
function splitMatches(text, query) {
|
|
346
|
+
if (!isDefined(query)) return [{
|
|
347
|
+
text,
|
|
348
|
+
start: 0,
|
|
349
|
+
match: !1
|
|
350
|
+
}];
|
|
351
|
+
let pattern = query.split(" ").map((word) => word.replaceAll(/[$()*+.?[\\\]^{|}]/gu, String.raw`\$&`)).join(String.raw`[\s-]+`), parts = text.split(RegExp(`(${pattern})`, "giu"));
|
|
352
|
+
return parts.map((part, index) => ({
|
|
353
|
+
text: part,
|
|
354
|
+
start: parts.slice(0, index).join("").length,
|
|
355
|
+
match: index % 2 == 1
|
|
356
|
+
}));
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Narrows the library to the named icons, in the order given. Unknown names are skipped, so a list keeps working
|
|
360
|
+
* across library releases.
|
|
234
361
|
*
|
|
235
|
-
* @param library - Every icon the library
|
|
236
|
-
* @param names -
|
|
237
|
-
* @returns The icons
|
|
362
|
+
* @param library - Every icon in the library.
|
|
363
|
+
* @param names - The icons to offer, or undefined for all of them.
|
|
364
|
+
* @returns The icons to offer.
|
|
238
365
|
*/
|
|
239
366
|
function selectIcons(library, names) {
|
|
240
367
|
if (!isDefined(names)) return library;
|
|
@@ -245,165 +372,320 @@ function selectIcons(library, names) {
|
|
|
245
372
|
});
|
|
246
373
|
}
|
|
247
374
|
/**
|
|
248
|
-
*
|
|
249
|
-
* from the same release as the icons themselves, so the drawings and their terms never disagree.
|
|
375
|
+
* Lists identifiers as inline code, separated by commas.
|
|
250
376
|
*
|
|
251
|
-
* @
|
|
377
|
+
* @param identifiers - The identifiers.
|
|
378
|
+
* @returns The list.
|
|
252
379
|
*/
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
380
|
+
function formatList(identifiers) {
|
|
381
|
+
return identifiers.map((identifier) => `\`${identifier}\``).join(", ");
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Describes why a library the project hasn't installed can't be shown, and what to add.
|
|
385
|
+
*
|
|
386
|
+
* @param label - Readable name of the library.
|
|
387
|
+
* @param packageName - Package the library is read from, or an example of one for a family of packages.
|
|
388
|
+
* @param family - Whether the library is a family of packages, one per style.
|
|
389
|
+
* @param listed - Whether the project's `package.json` lists the package.
|
|
390
|
+
* @param sitePackage - Another package of the library the project lists, or undefined when there's none.
|
|
391
|
+
* @returns The problem.
|
|
392
|
+
*/
|
|
393
|
+
function describeMissingLibrary(label, packageName, family, listed, sitePackage) {
|
|
394
|
+
return listed ? {
|
|
395
|
+
title: `${label} isn't installed yet`,
|
|
396
|
+
description: `\`${packageName}\` is in \`package.json\` but not in \`node_modules\`. Reinstall the project's dependencies.`
|
|
397
|
+
} : isDefined(sitePackage) ? {
|
|
398
|
+
title: `${label} needs \`${packageName}\``,
|
|
399
|
+
description: `The Studio reads ${label} from \`${packageName}\`, not \`${sitePackage}\`. Add it as a dev dependency.`
|
|
400
|
+
} : {
|
|
401
|
+
title: `${label} isn't installed`,
|
|
402
|
+
description: family ? `Install a ${label} style package, such as \`${packageName}\`.` : `Install \`${packageName}\` in the project.`
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Loads one library style from the sets the build step converted.
|
|
407
|
+
*
|
|
408
|
+
* @param library - Identifier of the library, or undefined when none is set.
|
|
409
|
+
* @param style - Identifier of the style, or undefined for the library's default.
|
|
410
|
+
* @returns The icons, or why they can't be shown.
|
|
411
|
+
*/
|
|
412
|
+
async function readLibrary(library, style) {
|
|
413
|
+
if (!isDefined(library)) return { problem: {
|
|
414
|
+
title: "No icon library set",
|
|
415
|
+
description: "Set `library` in the icon plugin's configuration or in the field's options."
|
|
416
|
+
} };
|
|
417
|
+
if (!iconRegistry.ready) return { problem: {
|
|
418
|
+
title: "Icons aren't set up",
|
|
419
|
+
description: "Add `withIcons()` to the Studio's build configuration, then restart the Studio."
|
|
420
|
+
} };
|
|
421
|
+
let info = iconRegistry.libraries[library];
|
|
422
|
+
if (!isDefined(info)) return { problem: {
|
|
423
|
+
title: "Unknown icon library",
|
|
424
|
+
description: `There's no icon library called \`${library}\`. Use one of: ${formatList(Object.keys(iconRegistry.libraries))}.`
|
|
425
|
+
} };
|
|
426
|
+
let { label, packageName, packagePrefix, styles, listed, installed, sitePackage } = info;
|
|
427
|
+
if (!installed) return { problem: describeMissingLibrary(label, packageName, isDefined(packagePrefix), listed, sitePackage) };
|
|
428
|
+
let resolvedStyle = style ?? styles[0] ?? "", loader = iconRegistry.sets[getIconSetKey(library, resolvedStyle)];
|
|
429
|
+
if (!isDefined(loader)) return { problem: isDefined(packagePrefix) ? {
|
|
430
|
+
title: `${label} style \`${resolvedStyle}\` isn't installed`,
|
|
431
|
+
description: `Install \`${packagePrefix}${resolvedStyle}\` in the project.`
|
|
432
|
+
} : {
|
|
433
|
+
title: `Unknown ${label} style`,
|
|
434
|
+
description: `${label} has no \`${resolvedStyle}\` style. Use one of: ${formatList(styles)}.`
|
|
435
|
+
} };
|
|
436
|
+
let module = await loader(), set = parseIconSet(module.default);
|
|
437
|
+
return isDefined(set) ? { icons: set.icons.map(({ name, keywords, node, root }) => ({
|
|
438
|
+
name,
|
|
439
|
+
label: convertCase(name, "title"),
|
|
440
|
+
tags: keywords.join(", "),
|
|
441
|
+
drawing: {
|
|
442
|
+
root: root ?? set.root,
|
|
443
|
+
node
|
|
444
|
+
},
|
|
445
|
+
terms: normalizeTerms([name, ...keywords].join(" "))
|
|
446
|
+
})) } : { problem: {
|
|
447
|
+
title: `Couldn't load ${label}`,
|
|
448
|
+
description: "Restart the Studio and try again."
|
|
449
|
+
} };
|
|
267
450
|
}
|
|
268
|
-
/**
|
|
269
|
-
|
|
451
|
+
/** Library requests shared by every field in the session, keyed by library and style, since the data never changes. */
|
|
452
|
+
const libraryRequests = /* @__PURE__ */ new Map();
|
|
270
453
|
/**
|
|
271
|
-
*
|
|
272
|
-
* library is a megabyte of data that never changes within a release, so asking twice only ever costs.
|
|
454
|
+
* Loads a library style, reusing a request already in progress.
|
|
273
455
|
*
|
|
274
|
-
* @
|
|
456
|
+
* @param library - Identifier of the library, or undefined when none is set.
|
|
457
|
+
* @param style - Identifier of the style, or undefined for the library's default.
|
|
458
|
+
* @returns The icons, or why they can't be shown.
|
|
459
|
+
*/
|
|
460
|
+
async function requestLibrary(library, style) {
|
|
461
|
+
let key = getIconSetKey(library ?? "", style ?? ""), request = libraryRequests.get(key);
|
|
462
|
+
return isDefined(request) || (request = readLibrary(library, style), libraryRequests.set(key, request)), await request;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Gap between the tooltip and its cell, set through margins because `@sanity/ui` offers no other way.
|
|
466
|
+
* Only the top is set, since the tooltip always appears above the cell.
|
|
275
467
|
*/
|
|
276
|
-
|
|
277
|
-
|
|
468
|
+
const tooltipMargins = [
|
|
469
|
+
-4,
|
|
470
|
+
0,
|
|
471
|
+
0,
|
|
472
|
+
0
|
|
473
|
+
], matchStyle = {
|
|
474
|
+
background: "none",
|
|
475
|
+
color: "inherit",
|
|
476
|
+
textDecorationLine: "underline",
|
|
477
|
+
textUnderlineOffset: "0.2em"
|
|
478
|
+
};
|
|
479
|
+
function Highlight(t0) {
|
|
480
|
+
let $ = c(10), props, query, text;
|
|
481
|
+
$[0] === t0 ? (props = $[1], query = $[2], text = $[3]) : ({text, query, ...props} = t0, $[0] = t0, $[1] = props, $[2] = query, $[3] = text);
|
|
482
|
+
let t1;
|
|
483
|
+
$[4] !== query || $[5] !== text ? (t1 = splitMatches(text, query).map(_temp$1), $[4] = query, $[5] = text, $[6] = t1) : t1 = $[6];
|
|
484
|
+
let t2;
|
|
485
|
+
return $[7] !== props || $[8] !== t1 ? (t2 = /* @__PURE__ */ jsx("span", {
|
|
486
|
+
...props,
|
|
487
|
+
children: t1
|
|
488
|
+
}), $[7] = props, $[8] = t1, $[9] = t2) : t2 = $[9], t2;
|
|
489
|
+
}
|
|
490
|
+
function _temp$1(part) {
|
|
491
|
+
return part.match ? /* @__PURE__ */ jsx("mark", {
|
|
492
|
+
style: matchStyle,
|
|
493
|
+
children: part.text
|
|
494
|
+
}, part.start) : part.text;
|
|
495
|
+
}
|
|
496
|
+
function Tooltip(t0) {
|
|
497
|
+
let $ = c(15), hovered, props, query;
|
|
498
|
+
$[0] === t0 ? (hovered = $[1], props = $[2], query = $[3]) : ({hovered, query, ...props} = t0, $[0] = t0, $[1] = hovered, $[2] = props, $[3] = query);
|
|
499
|
+
let t1;
|
|
500
|
+
$[4] === hovered ? t1 = $[5] : (t1 = isDefined(hovered), $[4] = hovered, $[5] = t1);
|
|
501
|
+
let t2 = hovered?.element ?? null, t3;
|
|
502
|
+
$[6] === Symbol.for("react.memo_cache_sentinel") ? (t3 = { pointerEvents: "none" }, $[6] = t3) : t3 = $[6];
|
|
503
|
+
let t4;
|
|
504
|
+
$[7] !== hovered || $[8] !== query ? (t4 = isDefined(hovered) && /* @__PURE__ */ jsxs(Stack, {
|
|
505
|
+
gap: 3,
|
|
506
|
+
style: { maxWidth: "16rem" },
|
|
507
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
508
|
+
size: 1,
|
|
509
|
+
weight: "medium",
|
|
510
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
511
|
+
text: hovered.icon.label,
|
|
512
|
+
query
|
|
513
|
+
})
|
|
514
|
+
}), isDefined(hovered.icon.tags) && /* @__PURE__ */ jsx(Text, {
|
|
515
|
+
size: 1,
|
|
516
|
+
muted: !0,
|
|
517
|
+
children: /* @__PURE__ */ jsx(Highlight, {
|
|
518
|
+
text: hovered.icon.tags,
|
|
519
|
+
query
|
|
520
|
+
})
|
|
521
|
+
})]
|
|
522
|
+
}), $[7] = hovered, $[8] = query, $[9] = t4) : t4 = $[9];
|
|
523
|
+
let t5;
|
|
524
|
+
return $[10] !== props || $[11] !== t1 || $[12] !== t2 || $[13] !== t4 ? (t5 = /* @__PURE__ */ jsx(Popover, {
|
|
525
|
+
open: t1,
|
|
526
|
+
referenceElement: t2,
|
|
527
|
+
placement: "top",
|
|
528
|
+
portal: !0,
|
|
529
|
+
padding: 3,
|
|
530
|
+
__unstable_margins: tooltipMargins,
|
|
531
|
+
style: t3,
|
|
532
|
+
content: t4,
|
|
533
|
+
...props
|
|
534
|
+
}), $[10] = props, $[11] = t1, $[12] = t2, $[13] = t4, $[14] = t5) : t5 = $[14], t5;
|
|
278
535
|
}
|
|
279
536
|
/**
|
|
280
|
-
*
|
|
281
|
-
* only while a picker is open, so a Studio that never opens one never pays the megabyte it costs.
|
|
537
|
+
* Loads an icon library style. Only an open picker calls this, so a Studio that never opens one never loads it.
|
|
282
538
|
*
|
|
283
|
-
* @
|
|
539
|
+
* @param library - Identifier of the library, or undefined when none is set.
|
|
540
|
+
* @param style - Identifier of the style, or undefined for the library's default.
|
|
541
|
+
* @returns The icons or why they can't be shown, or undefined while loading.
|
|
284
542
|
*/
|
|
285
|
-
function useIconLibrary() {
|
|
286
|
-
let $ = c(
|
|
287
|
-
return $[0]
|
|
543
|
+
function useIconLibrary(library, style) {
|
|
544
|
+
let $ = c(4), [result, setResult] = useState(), t0, t1;
|
|
545
|
+
return $[0] !== library || $[1] !== style ? (t0 = () => {
|
|
288
546
|
let active = !0;
|
|
289
547
|
return (async function load() {
|
|
290
|
-
let loaded = await requestLibrary();
|
|
291
|
-
active &&
|
|
548
|
+
let loaded = await requestLibrary(library, style);
|
|
549
|
+
active && setResult(loaded);
|
|
292
550
|
})(), () => {
|
|
293
551
|
active = !1;
|
|
294
552
|
};
|
|
295
|
-
}, t1 = [], $[0] =
|
|
553
|
+
}, t1 = [library, style], $[0] = library, $[1] = style, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1), result;
|
|
296
554
|
}
|
|
297
555
|
/**
|
|
298
|
-
* Tracks
|
|
556
|
+
* Tracks the icon under the cursor, showing its tooltip after a short delay. Tooltips are held back while the grid
|
|
557
|
+
* scrolls, and the icon left under the cursor gets its tooltip once scrolling stops.
|
|
299
558
|
*
|
|
300
|
-
* @param
|
|
301
|
-
* @
|
|
302
|
-
* @returns The icon being hovered, alongside ways to follow the cursor and to dismiss it.
|
|
559
|
+
* @param scrolling - Whether the grid is scrolling.
|
|
560
|
+
* @returns The hovered icon, and functions to update and clear it.
|
|
303
561
|
*/
|
|
304
|
-
function useIconTooltip(
|
|
305
|
-
let $ = c(
|
|
562
|
+
function useIconTooltip(scrolling) {
|
|
563
|
+
let $ = c(14), [hovered, setHovered] = useState(), hoverStart = useRef(void 0), scrolledOnto = useRef(void 0), t0, t1;
|
|
306
564
|
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => () => {
|
|
307
565
|
isDefined(hoverStart.current) && clearTimeout(hoverStart.current);
|
|
308
566
|
}, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), useEffect(t0, t1);
|
|
309
|
-
let t2;
|
|
310
|
-
$[2] ===
|
|
567
|
+
let t2, t3;
|
|
568
|
+
$[2] === scrolling ? (t2 = $[3], t3 = $[4]) : (t2 = () => {
|
|
569
|
+
let landed = scrolledOnto.current;
|
|
570
|
+
!scrolling && isDefined(landed) && (scrolledOnto.current = void 0, landed.element.isConnected && landed.element.matches(":hover") && (hoverStart.current = setTimeout(() => {
|
|
571
|
+
setHovered(landed);
|
|
572
|
+
}, 200)));
|
|
573
|
+
}, t3 = [scrolling], $[2] = scrolling, $[3] = t2, $[4] = t3), useEffect(t2, t3);
|
|
574
|
+
let t4;
|
|
575
|
+
$[5] === hovered ? t4 = $[6] : (t4 = function clearHover() {
|
|
311
576
|
isDefined(hoverStart.current) && clearTimeout(hoverStart.current), isDefined(hovered) && setHovered(void 0);
|
|
312
|
-
}, $[
|
|
313
|
-
let clearHover =
|
|
314
|
-
$[
|
|
315
|
-
if (scrolling)
|
|
316
|
-
|
|
317
|
-
if (cell === hovered?.element) return;
|
|
318
|
-
let name = cell?.dataset.icon, icon = isDefined(name) ? byName.get(name) : void 0;
|
|
319
|
-
if (isDefined(hoverStart.current) && clearTimeout(hoverStart.current), !isDefined(icon) || !isDefined(cell)) {
|
|
320
|
-
setHovered(void 0);
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
if (isDefined(hovered)) {
|
|
324
|
-
setHovered({
|
|
577
|
+
}, $[5] = hovered, $[6] = t4);
|
|
578
|
+
let clearHover = t4, t5;
|
|
579
|
+
$[7] !== hovered || $[8] !== scrolling ? (t5 = function handleHover(icon, element) {
|
|
580
|
+
if (scrolling) {
|
|
581
|
+
scrolledOnto.current = {
|
|
325
582
|
icon,
|
|
326
|
-
element
|
|
327
|
-
}
|
|
583
|
+
element
|
|
584
|
+
};
|
|
328
585
|
return;
|
|
329
586
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
587
|
+
if (element !== hovered?.element) {
|
|
588
|
+
if (isDefined(hoverStart.current) && clearTimeout(hoverStart.current), isDefined(hovered)) {
|
|
589
|
+
setHovered({
|
|
590
|
+
icon,
|
|
591
|
+
element
|
|
592
|
+
});
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
hoverStart.current = setTimeout(() => {
|
|
596
|
+
setHovered({
|
|
597
|
+
icon,
|
|
598
|
+
element
|
|
599
|
+
});
|
|
600
|
+
}, 200);
|
|
601
|
+
}
|
|
602
|
+
}, $[7] = hovered, $[8] = scrolling, $[9] = t5) : t5 = $[9];
|
|
603
|
+
let handleHover = t5, t6;
|
|
604
|
+
return $[10] !== clearHover || $[11] !== handleHover || $[12] !== hovered ? (t6 = {
|
|
339
605
|
hovered,
|
|
340
606
|
handleHover,
|
|
341
607
|
clearHover
|
|
342
|
-
}, $[
|
|
608
|
+
}, $[10] = clearHover, $[11] = handleHover, $[12] = hovered, $[13] = t6) : t6 = $[13], t6;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Builds the storage key for one library style.
|
|
612
|
+
*
|
|
613
|
+
* @param scope - The library and style, such as `phosphor/bold`.
|
|
614
|
+
* @returns The storage key.
|
|
615
|
+
*/
|
|
616
|
+
function getStorageKey(scope) {
|
|
617
|
+
return `driftime:sanity-plugin-icon:recent:${scope}`;
|
|
343
618
|
}
|
|
344
|
-
/** Where the icons an author reached for last are kept, in the browser rather than the dataset. */
|
|
345
|
-
const storageKey = "driftime:sanity-plugin-icon:recent";
|
|
346
619
|
/**
|
|
347
|
-
* Reads the
|
|
620
|
+
* Reads the recently chosen icons.
|
|
348
621
|
*
|
|
349
|
-
* @
|
|
622
|
+
* @param scope - The library and style, such as `phosphor/bold`.
|
|
623
|
+
* @returns The icon names, most recent first.
|
|
350
624
|
*/
|
|
351
|
-
function readRecent() {
|
|
625
|
+
function readRecent(scope) {
|
|
352
626
|
try {
|
|
353
|
-
let stored = JSON.parse(globalThis.localStorage.getItem(
|
|
627
|
+
let stored = JSON.parse(globalThis.localStorage.getItem(getStorageKey(scope)) ?? "[]");
|
|
354
628
|
return Array.isArray(stored) ? stored.filter((entry) => typeof entry == "string") : [];
|
|
355
629
|
} catch {
|
|
356
630
|
return [];
|
|
357
631
|
}
|
|
358
632
|
}
|
|
359
633
|
/**
|
|
360
|
-
*
|
|
634
|
+
* Adds an icon to the front of the recent list.
|
|
361
635
|
*
|
|
362
|
-
* @param
|
|
363
|
-
* @
|
|
636
|
+
* @param scope - The library and style, such as `phosphor/bold`.
|
|
637
|
+
* @param name - The chosen icon's name.
|
|
638
|
+
* @returns The updated icon names, most recent first.
|
|
364
639
|
*/
|
|
365
|
-
function writeRecent(name) {
|
|
366
|
-
let updated = [name, ...readRecent().filter((entry) => entry !== name)].slice(0, 8);
|
|
640
|
+
function writeRecent(scope, name) {
|
|
641
|
+
let updated = [name, ...readRecent(scope).filter((entry) => entry !== name)].slice(0, 8);
|
|
367
642
|
try {
|
|
368
|
-
globalThis.localStorage.setItem(
|
|
643
|
+
globalThis.localStorage.setItem(getStorageKey(scope), JSON.stringify(updated));
|
|
369
644
|
} catch {}
|
|
370
645
|
return updated;
|
|
371
646
|
}
|
|
372
|
-
/**
|
|
373
|
-
|
|
647
|
+
/**
|
|
648
|
+
* Clears the recent icons.
|
|
649
|
+
*
|
|
650
|
+
* @param scope - The library and style, such as `phosphor/bold`.
|
|
651
|
+
*/
|
|
652
|
+
function clearRecent(scope) {
|
|
374
653
|
try {
|
|
375
|
-
globalThis.localStorage.removeItem(
|
|
654
|
+
globalThis.localStorage.removeItem(getStorageKey(scope));
|
|
376
655
|
} catch {}
|
|
377
656
|
}
|
|
378
657
|
/**
|
|
379
|
-
* Tracks the icons an author
|
|
380
|
-
*
|
|
658
|
+
* Tracks the icons an author chose most recently from one library style. The list is read when the picker opens, so
|
|
659
|
+
* choices made in another tab are included.
|
|
381
660
|
*
|
|
382
|
-
* @
|
|
661
|
+
* @param scope - The library and style, such as `phosphor/bold`.
|
|
662
|
+
* @returns The recent icon names, most recent first, and functions to add to and clear them.
|
|
383
663
|
*/
|
|
384
|
-
function useRecentIcons() {
|
|
385
|
-
let $ = c(
|
|
386
|
-
$[0] ===
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
$[
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
664
|
+
function useRecentIcons(scope) {
|
|
665
|
+
let $ = c(10), t0;
|
|
666
|
+
$[0] === scope ? t0 = $[1] : (t0 = () => readRecent(scope), $[0] = scope, $[1] = t0);
|
|
667
|
+
let [recent, setRecent] = useState(t0), t1;
|
|
668
|
+
$[2] === scope ? t1 = $[3] : (t1 = function remember(name) {
|
|
669
|
+
setRecent(writeRecent(scope, name));
|
|
670
|
+
}, $[2] = scope, $[3] = t1);
|
|
671
|
+
let remember = t1, t2;
|
|
672
|
+
$[4] === scope ? t2 = $[5] : (t2 = function forget() {
|
|
673
|
+
clearRecent(scope), setRecent([]);
|
|
674
|
+
}, $[4] = scope, $[5] = t2);
|
|
675
|
+
let forget = t2, t3;
|
|
676
|
+
return $[6] !== forget || $[7] !== recent || $[8] !== remember ? (t3 = {
|
|
395
677
|
recent,
|
|
396
678
|
remember,
|
|
397
679
|
forget
|
|
398
|
-
}, $[
|
|
680
|
+
}, $[6] = forget, $[7] = recent, $[8] = remember, $[9] = t3) : t3 = $[9], t3;
|
|
399
681
|
}
|
|
400
682
|
/**
|
|
401
|
-
* Works out which icon a key press moves to
|
|
683
|
+
* Works out which icon a key press moves to.
|
|
402
684
|
*
|
|
403
685
|
* @param key - The key pressed.
|
|
404
|
-
* @param current - Index of the icon
|
|
405
|
-
* @param last - Index of the
|
|
406
|
-
* @returns The index
|
|
686
|
+
* @param current - Index of the current icon.
|
|
687
|
+
* @param last - Index of the last icon.
|
|
688
|
+
* @returns The new index, or undefined when the key doesn't move.
|
|
407
689
|
*/
|
|
408
690
|
function getNextIndex(key, current, last) {
|
|
409
691
|
if (key === "ArrowRight") return current + 1;
|
|
@@ -414,12 +696,12 @@ function getNextIndex(key, current, last) {
|
|
|
414
696
|
if (key === "End") return last;
|
|
415
697
|
}
|
|
416
698
|
/**
|
|
417
|
-
* Works out which rows
|
|
418
|
-
*
|
|
699
|
+
* Works out which rows to render at a scroll position, so only icons near the viewport are mounted.
|
|
700
|
+
* Padding replaces the other rows, so the scrollbar stays the right size.
|
|
419
701
|
*
|
|
420
|
-
* @param scrollRow -
|
|
702
|
+
* @param scrollRow - The row scrolled to.
|
|
421
703
|
* @param count - Number of icons in the results.
|
|
422
|
-
* @returns The
|
|
704
|
+
* @returns The first and last rows to render, and the total number of rows.
|
|
423
705
|
*/
|
|
424
706
|
function getVisibleRows(scrollRow, count) {
|
|
425
707
|
let totalRows = Math.ceil(count / 8), firstRow = Math.max(0, scrollRow - 8);
|
|
@@ -430,58 +712,56 @@ function getVisibleRows(scrollRow, count) {
|
|
|
430
712
|
};
|
|
431
713
|
}
|
|
432
714
|
/**
|
|
433
|
-
* Works out
|
|
434
|
-
* icon already chosen.
|
|
715
|
+
* Works out the scroll position that centres an icon, for opening on the selected icon.
|
|
435
716
|
*
|
|
436
|
-
* @param index - Index of the icon
|
|
437
|
-
* @returns The
|
|
717
|
+
* @param index - Index of the icon.
|
|
718
|
+
* @returns The scroll position.
|
|
438
719
|
*/
|
|
439
|
-
function
|
|
720
|
+
function getCenteredScrollTop(index) {
|
|
440
721
|
return Math.max(0, Math.floor(index / 8) * 44 - 174);
|
|
441
722
|
}
|
|
442
723
|
/**
|
|
443
|
-
* Works out
|
|
444
|
-
*
|
|
445
|
-
* land outside the rows that are mounted.
|
|
724
|
+
* Works out the scroll position that brings an icon into view, keeping the current one if it's
|
|
725
|
+
* already visible. It uses the index because Home and End can move to rows that aren't mounted.
|
|
446
726
|
*
|
|
447
|
-
* @param index - Index of the icon
|
|
448
|
-
* @param scrollTop -
|
|
449
|
-
* @returns The
|
|
727
|
+
* @param index - Index of the icon.
|
|
728
|
+
* @param scrollTop - The current scroll position.
|
|
729
|
+
* @returns The scroll position.
|
|
450
730
|
*/
|
|
451
731
|
function getRevealedScrollTop(index, scrollTop) {
|
|
452
732
|
let top = Math.floor(index / 8) * 44;
|
|
453
733
|
return top < scrollTop ? top : top + 44 > scrollTop + 348 ? top + 44 - 348 : scrollTop;
|
|
454
734
|
}
|
|
455
735
|
function Picker(t0) {
|
|
456
|
-
let $ = c(
|
|
457
|
-
$[0] === t0 ? (allowed = $[1],
|
|
458
|
-
let
|
|
736
|
+
let $ = c(39), allowed, iconStyle, libraryName, onSelect, props, selected;
|
|
737
|
+
$[0] === t0 ? (allowed = $[1], iconStyle = $[2], libraryName = $[3], onSelect = $[4], props = $[5], selected = $[6]) : ({library: libraryName, iconStyle, allowed, selected, onSelect, ...props} = t0, $[0] = t0, $[1] = allowed, $[2] = iconStyle, $[3] = libraryName, $[4] = onSelect, $[5] = props, $[6] = selected);
|
|
738
|
+
let result = useIconLibrary(libraryName, iconStyle), library = result?.icons, icons = selectIcons(library ?? [], allowed), t1 = libraryName ?? "", t2 = iconStyle ?? "default", t3;
|
|
739
|
+
$[7] !== t1 || $[8] !== t2 ? (t3 = getIconSetKey(t1, t2), $[7] = t1, $[8] = t2, $[9] = t3) : t3 = $[9];
|
|
740
|
+
let { recent, remember, forget } = useRecentIcons(t3), [search, setSearch] = useState(""), [scrollRow, setScrollRow] = useState(0), [movedIndex, setMovedIndex] = useState(), [scrolling, setScrolling] = useState(!1), scroller = useRef(null), activeCell = useRef(null), focusIndex = useRef(void 0), scrollFrame = useRef(void 0), scrollStop = useRef(void 0), query = normalizeTerms(search), searching = isDefined(query), results = icons.filter((icon) => !searching || icon.terms.includes(query)), byName = new Map(icons.map(_temp)), recentIcons = searching ? [] : recent.flatMap((entry) => {
|
|
459
741
|
let icon_1 = byName.get(entry);
|
|
460
742
|
return isDefined(icon_1) ? [icon_1] : [];
|
|
461
|
-
}), { hovered, handleHover, clearHover } = useIconTooltip(
|
|
743
|
+
}), { hovered, handleHover, clearHover } = useIconTooltip(scrolling), rows = getVisibleRows(scrollRow, results.length), selectedIndex = searching || !isDefined(selected) ? -1 : icons.findIndex((icon_2) => icon_2.name === selected), activeIndex = movedIndex ?? Math.max(0, selectedIndex);
|
|
462
744
|
useEffect(() => {
|
|
463
745
|
let element = scroller.current;
|
|
464
|
-
isDefined(element) && selectedIndex !== -1 && (element.scrollTop =
|
|
465
|
-
}, [selectedIndex]);
|
|
466
|
-
let
|
|
467
|
-
$[
|
|
746
|
+
isDefined(element) && selectedIndex !== -1 && (element.scrollTop = getCenteredScrollTop(selectedIndex));
|
|
747
|
+
}, [scroller, selectedIndex]);
|
|
748
|
+
let t4, t5;
|
|
749
|
+
$[10] === Symbol.for("react.memo_cache_sentinel") ? (t4 = () => () => {
|
|
468
750
|
isDefined(scrollFrame.current) && cancelAnimationFrame(scrollFrame.current), isDefined(scrollStop.current) && clearTimeout(scrollStop.current);
|
|
469
|
-
},
|
|
470
|
-
let
|
|
471
|
-
$[
|
|
472
|
-
|
|
473
|
-
}, $[
|
|
474
|
-
let
|
|
475
|
-
$[
|
|
476
|
-
let t5;
|
|
477
|
-
$[10] !== onSelect || $[11] !== remember ? (t5 = function handleSelect(icon_3) {
|
|
751
|
+
}, t5 = [], $[10] = t4, $[11] = t5) : (t4 = $[10], t5 = $[11]), useEffect(t4, t5);
|
|
752
|
+
let t6, t7;
|
|
753
|
+
$[12] === activeIndex ? (t6 = $[13], t7 = $[14]) : (t6 = () => {
|
|
754
|
+
focusIndex.current === activeIndex && (focusIndex.current = void 0, isDefined(activeCell.current) && activeCell.current.focus());
|
|
755
|
+
}, t7 = [activeIndex], $[12] = activeIndex, $[13] = t6, $[14] = t7), useEffect(t6, t7);
|
|
756
|
+
let t8;
|
|
757
|
+
$[15] !== onSelect || $[16] !== remember ? (t8 = function handleSelect(icon_3) {
|
|
478
758
|
remember(icon_3.name), onSelect(icon_3);
|
|
479
|
-
}, $[
|
|
480
|
-
let handleSelect =
|
|
481
|
-
$[
|
|
759
|
+
}, $[15] = onSelect, $[16] = remember, $[17] = t8) : t8 = $[17];
|
|
760
|
+
let handleSelect = t8, t9;
|
|
761
|
+
$[18] === Symbol.for("react.memo_cache_sentinel") ? (t9 = function clearSearch() {
|
|
482
762
|
setSearch(""), setMovedIndex(void 0);
|
|
483
|
-
}, $[
|
|
484
|
-
let clearSearch =
|
|
763
|
+
}, $[18] = t9) : t9 = $[18];
|
|
764
|
+
let clearSearch = t9, handleSearch = function handleSearch(event) {
|
|
485
765
|
setSearch(event.currentTarget.value), setMovedIndex(void 0), isDefined(scroller.current) && (scroller.current.scrollTop = 0);
|
|
486
766
|
}, selectActive = function selectActive() {
|
|
487
767
|
let icon_4 = results[activeIndex];
|
|
@@ -511,20 +791,35 @@ function Picker(t0) {
|
|
|
511
791
|
if (!isDefined(next)) return;
|
|
512
792
|
event_1.preventDefault();
|
|
513
793
|
let index = Math.min(Math.max(next, 0), last);
|
|
514
|
-
|
|
794
|
+
focusIndex.current = index, setMovedIndex(index);
|
|
515
795
|
let element_1 = scroller.current;
|
|
516
796
|
isDefined(element_1) && (element_1.scrollTop = getRevealedScrollTop(index, element_1.scrollTop));
|
|
517
|
-
},
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
797
|
+
}, T0 = Dialog, T1 = Stack, t14 = !isDefined(result?.problem) && /* @__PURE__ */ jsx(TextInput, {
|
|
798
|
+
type: "search",
|
|
799
|
+
icon: /* @__PURE__ */ jsx(SearchIcon, {}),
|
|
800
|
+
placeholder: "Search by name or keyword",
|
|
801
|
+
value: search,
|
|
802
|
+
onChange: handleSearch,
|
|
803
|
+
onKeyDown: handleSearchKeyDown,
|
|
804
|
+
disabled: !isDefined(library) || !isDefined(icons),
|
|
805
|
+
"aria-label": "Search the icon library"
|
|
806
|
+
}), t15;
|
|
807
|
+
$[19] === result ? t15 = $[20] : (t15 = !isDefined(result) && /* @__PURE__ */ jsx(Flex, {
|
|
521
808
|
align: "center",
|
|
522
809
|
justify: "center",
|
|
523
810
|
style: { height: 348 },
|
|
524
811
|
children: /* @__PURE__ */ jsx(Spinner, { muted: !0 })
|
|
525
|
-
}), $[
|
|
526
|
-
let
|
|
527
|
-
$[
|
|
812
|
+
}), $[19] = result, $[20] = t15);
|
|
813
|
+
let t16;
|
|
814
|
+
$[21] === result ? t16 = $[22] : (t16 = isDefined(result?.problem) && /* @__PURE__ */ jsx(Problem, { problem: result.problem }), $[21] = result, $[22] = t16);
|
|
815
|
+
let t17 = isDefined(recentIcons) && /* @__PURE__ */ jsx(Recent, {
|
|
816
|
+
icons: recentIcons,
|
|
817
|
+
selected,
|
|
818
|
+
onSelect: handleSelect,
|
|
819
|
+
onHover: handleHover,
|
|
820
|
+
onForget: forget,
|
|
821
|
+
onMouseLeave: clearHover
|
|
822
|
+
}), t18 = isDefined(library) && /* @__PURE__ */ jsxs(Stack, {
|
|
528
823
|
gap: 3,
|
|
529
824
|
children: [
|
|
530
825
|
/* @__PURE__ */ jsx(Box, {
|
|
@@ -535,22 +830,23 @@ function Picker(t0) {
|
|
|
535
830
|
muted: !0,
|
|
536
831
|
children: [
|
|
537
832
|
"All icons (",
|
|
538
|
-
results.length.toLocaleString("en-
|
|
833
|
+
results.length.toLocaleString("en-US"),
|
|
539
834
|
")"
|
|
540
835
|
]
|
|
541
836
|
})
|
|
542
837
|
}),
|
|
543
|
-
icons
|
|
838
|
+
!isDefined(icons) && /* @__PURE__ */ jsx(Flex, {
|
|
544
839
|
align: "center",
|
|
545
840
|
justify: "center",
|
|
546
|
-
|
|
841
|
+
paddingTop: 5,
|
|
842
|
+
paddingBottom: 6,
|
|
547
843
|
children: /* @__PURE__ */ jsx(Text, {
|
|
548
844
|
size: 1,
|
|
549
845
|
muted: !0,
|
|
550
|
-
children: "No icons
|
|
846
|
+
children: "No icons available."
|
|
551
847
|
})
|
|
552
848
|
}),
|
|
553
|
-
icons
|
|
849
|
+
isDefined(icons) && /* @__PURE__ */ jsx(Library, {
|
|
554
850
|
ref: scroller,
|
|
555
851
|
icons: results,
|
|
556
852
|
rows,
|
|
@@ -559,105 +855,151 @@ function Picker(t0) {
|
|
|
559
855
|
activeCell,
|
|
560
856
|
search,
|
|
561
857
|
onSelect: handleSelect,
|
|
858
|
+
onHover: handleHover,
|
|
562
859
|
onClearSearch: clearSearch,
|
|
563
860
|
onScroll: handleScroll,
|
|
564
|
-
onMouseOver: handleHover,
|
|
565
861
|
onMouseLeave: clearHover,
|
|
566
862
|
onKeyDown: handleGridKeyDown
|
|
567
863
|
})
|
|
568
864
|
]
|
|
569
|
-
}),
|
|
570
|
-
|
|
571
|
-
|
|
865
|
+
}), t19 = hovered?.icon.name, t20;
|
|
866
|
+
$[23] !== hovered || $[24] !== query || $[25] !== t19 ? (t20 = /* @__PURE__ */ jsx(Tooltip, {
|
|
867
|
+
hovered,
|
|
868
|
+
query
|
|
869
|
+
}, t19), $[23] = hovered, $[24] = query, $[25] = t19, $[26] = t20) : t20 = $[26];
|
|
870
|
+
let t21;
|
|
871
|
+
$[27] !== T1 || $[28] !== t14 || $[29] !== t15 || $[30] !== t16 || $[31] !== t17 || $[32] !== t18 || $[33] !== t20 ? (t21 = /* @__PURE__ */ jsxs(T1, {
|
|
872
|
+
gap: 4,
|
|
873
|
+
padding: 4,
|
|
874
|
+
children: [
|
|
875
|
+
t14,
|
|
876
|
+
t15,
|
|
877
|
+
t16,
|
|
878
|
+
t17,
|
|
879
|
+
t18,
|
|
880
|
+
t20
|
|
881
|
+
]
|
|
882
|
+
}), $[27] = T1, $[28] = t14, $[29] = t15, $[30] = t16, $[31] = t17, $[32] = t18, $[33] = t20, $[34] = t21) : t21 = $[34];
|
|
883
|
+
let t22;
|
|
884
|
+
return $[35] !== T0 || $[36] !== props || $[37] !== t21 ? (t22 = /* @__PURE__ */ jsx(T0, {
|
|
572
885
|
header: "Select icon",
|
|
573
886
|
width: 1,
|
|
574
887
|
...props,
|
|
575
|
-
children:
|
|
576
|
-
|
|
577
|
-
padding: 4,
|
|
578
|
-
children: [
|
|
579
|
-
/* @__PURE__ */ jsx(TextInput, {
|
|
580
|
-
icon: t7,
|
|
581
|
-
placeholder: "Search by name or by what the icon depicts",
|
|
582
|
-
value: search,
|
|
583
|
-
onChange: handleSearch,
|
|
584
|
-
onKeyDown: handleSearchKeyDown,
|
|
585
|
-
disabled: !isDefined(library) || icons.length === 0,
|
|
586
|
-
"aria-label": "Search the icon library"
|
|
587
|
-
}),
|
|
588
|
-
t8,
|
|
589
|
-
isDefined(recentIcons) && /* @__PURE__ */ jsx(Recent, {
|
|
590
|
-
icons: recentIcons,
|
|
591
|
-
selected,
|
|
592
|
-
onSelect: handleSelect,
|
|
593
|
-
onForget: forget,
|
|
594
|
-
onMouseOver: handleHover,
|
|
595
|
-
onMouseLeave: clearHover
|
|
596
|
-
}),
|
|
597
|
-
t9,
|
|
598
|
-
t11
|
|
599
|
-
]
|
|
600
|
-
})
|
|
601
|
-
});
|
|
888
|
+
children: t21
|
|
889
|
+
}), $[35] = T0, $[36] = props, $[37] = t21, $[38] = t22) : t22 = $[38], t22;
|
|
602
890
|
}
|
|
603
891
|
function _temp(icon_0) {
|
|
604
892
|
return [icon_0.name, icon_0];
|
|
605
893
|
}
|
|
606
|
-
|
|
894
|
+
function SquareDashedIcon(props) {
|
|
895
|
+
let $ = c(14), t0, t1, t10, t11, t2, t3, t4, t5, t6, t7, t8, t9;
|
|
896
|
+
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsx("path", { d: "M5 3a2 2 0 0 0-2 2" }), t1 = /* @__PURE__ */ jsx("path", { d: "M19 3a2 2 0 0 1 2 2" }), t2 = /* @__PURE__ */ jsx("path", { d: "M21 19a2 2 0 0 1-2 2" }), t3 = /* @__PURE__ */ jsx("path", { d: "M5 21a2 2 0 0 1-2-2" }), t4 = /* @__PURE__ */ jsx("path", { d: "M9 3h1" }), t5 = /* @__PURE__ */ jsx("path", { d: "M9 21h1" }), t6 = /* @__PURE__ */ jsx("path", { d: "M14 3h1" }), t7 = /* @__PURE__ */ jsx("path", { d: "M14 21h1" }), t8 = /* @__PURE__ */ jsx("path", { d: "M3 9v1" }), t9 = /* @__PURE__ */ jsx("path", { d: "M21 9v1" }), t10 = /* @__PURE__ */ jsx("path", { d: "M3 14v1" }), t11 = /* @__PURE__ */ jsx("path", { d: "M21 14v1" }), $[0] = t0, $[1] = t1, $[2] = t10, $[3] = t11, $[4] = t2, $[5] = t3, $[6] = t4, $[7] = t5, $[8] = t6, $[9] = t7, $[10] = t8, $[11] = t9) : (t0 = $[0], t1 = $[1], t10 = $[2], t11 = $[3], t2 = $[4], t3 = $[5], t4 = $[6], t5 = $[7], t6 = $[8], t7 = $[9], t8 = $[10], t9 = $[11]);
|
|
897
|
+
let t12;
|
|
898
|
+
return $[12] === props ? t12 = $[13] : (t12 = /* @__PURE__ */ jsxs("svg", {
|
|
899
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
900
|
+
width: 24,
|
|
901
|
+
height: 24,
|
|
902
|
+
viewBox: "0 0 24 24",
|
|
903
|
+
fill: "none",
|
|
904
|
+
stroke: "currentColor",
|
|
905
|
+
strokeWidth: 2,
|
|
906
|
+
strokeLinecap: "round",
|
|
907
|
+
strokeLinejoin: "round",
|
|
908
|
+
...props,
|
|
909
|
+
children: [
|
|
910
|
+
t0,
|
|
911
|
+
t1,
|
|
912
|
+
t2,
|
|
913
|
+
t3,
|
|
914
|
+
t4,
|
|
915
|
+
t5,
|
|
916
|
+
t6,
|
|
917
|
+
t7,
|
|
918
|
+
t8,
|
|
919
|
+
t9,
|
|
920
|
+
t10,
|
|
921
|
+
t11
|
|
922
|
+
]
|
|
923
|
+
}), $[12] = props, $[13] = t12), t12;
|
|
924
|
+
}
|
|
925
|
+
/**
|
|
926
|
+
* Resolves the library, style, and icons a field offers. A field that names a library replaces all three of the
|
|
927
|
+
* plugin's, and one that doesn't uses the plugin's.
|
|
928
|
+
*
|
|
929
|
+
* @param options - The field's options.
|
|
930
|
+
* @param config - The plugin configuration.
|
|
931
|
+
* @returns The field's settings, whose library is undefined when neither the field nor the plugin names one.
|
|
932
|
+
*/
|
|
933
|
+
function resolveIconOptions(options, config) {
|
|
934
|
+
let { library, style, icons } = (isDefined(options?.library) ? options : config) ?? {};
|
|
935
|
+
return {
|
|
936
|
+
library,
|
|
937
|
+
style,
|
|
938
|
+
icons
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
/** Schema type name of the icon object. */
|
|
607
942
|
const iconTypeName = "icon";
|
|
608
943
|
/**
|
|
609
|
-
* Creates the
|
|
610
|
-
*
|
|
944
|
+
* Creates the icon field input, bound to the plugin's configuration. A field's own icons replace the
|
|
945
|
+
* plugin's rather than adding to them.
|
|
611
946
|
*
|
|
612
|
-
* @param
|
|
947
|
+
* @param config - The plugin configuration.
|
|
613
948
|
* @returns The input component.
|
|
614
949
|
*/
|
|
615
|
-
function createInput(
|
|
950
|
+
function createInput(config) {
|
|
616
951
|
function Input(t0) {
|
|
617
|
-
let $ = c(
|
|
618
|
-
$[0]
|
|
952
|
+
let $ = c(35), { id, schemaType, value, onChange, readOnly } = t0, { library: storedLibrary, name, node } = value ?? {}, [open, setOpen] = useState(!1), t1;
|
|
953
|
+
$[0] === schemaType.options ? t1 = $[1] : (t1 = resolveIconOptions(schemaType.options, config), $[0] = schemaType.options, $[1] = t1);
|
|
954
|
+
let { library, style, icons } = t1, selectedDrawing = resolveIconDrawing(node), selectedName = storedLibrary === library ? name : void 0, selectedLabel = isDefined(name) ? convertCase(name, "title") : void 0, t2;
|
|
955
|
+
$[2] !== library || $[3] !== onChange || $[4] !== setOpen || $[5] !== style ? (t2 = function handleSelect(icon) {
|
|
619
956
|
onChange([
|
|
620
957
|
setIfMissing({ _type: iconTypeName }),
|
|
958
|
+
isDefined(library) ? set(library, ["library"]) : unset(["library"]),
|
|
959
|
+
isDefined(style) ? set(style, ["style"]) : unset(["style"]),
|
|
621
960
|
set(icon.name, ["name"]),
|
|
622
|
-
set(
|
|
961
|
+
set(serializeIconDrawing(icon.drawing), ["node"])
|
|
623
962
|
]), setOpen(!1);
|
|
624
|
-
}, $[
|
|
625
|
-
let handleSelect =
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
963
|
+
}, $[2] = library, $[3] = onChange, $[4] = setOpen, $[5] = style, $[6] = t2) : t2 = $[6];
|
|
964
|
+
let handleSelect = t2, T0 = Flex, T1 = Button, t6 = isDefined(selectedDrawing) ? /* @__PURE__ */ jsx(Drawing, {
|
|
965
|
+
drawing: selectedDrawing,
|
|
966
|
+
width: "1em",
|
|
967
|
+
height: "1em"
|
|
968
|
+
}) : /* @__PURE__ */ jsx(SquareDashedIcon, { ...defaultIconProps }), t7 = selectedLabel ?? "Select icon", t8;
|
|
969
|
+
$[7] === setOpen ? t8 = $[8] : (t8 = () => {
|
|
630
970
|
setOpen(!0);
|
|
631
|
-
}, $[
|
|
632
|
-
let
|
|
633
|
-
$[
|
|
971
|
+
}, $[7] = setOpen, $[8] = t8);
|
|
972
|
+
let t9 = isDefined(selectedLabel) ? `${selectedLabel} currently selected` : "Select icon", t10;
|
|
973
|
+
$[9] !== T1 || $[10] !== id || $[11] !== readOnly || $[12] !== t6 || $[13] !== t7 || $[14] !== t8 || $[15] !== t9 ? (t10 = /* @__PURE__ */ jsx(T1, {
|
|
634
974
|
id,
|
|
635
975
|
type: "button",
|
|
636
976
|
mode: "ghost",
|
|
637
|
-
icon:
|
|
638
|
-
text:
|
|
977
|
+
icon: t6,
|
|
978
|
+
text: t7,
|
|
639
979
|
disabled: readOnly,
|
|
640
|
-
onClick:
|
|
641
|
-
"aria-label":
|
|
642
|
-
}), $[
|
|
643
|
-
let
|
|
644
|
-
$[
|
|
980
|
+
onClick: t8,
|
|
981
|
+
"aria-label": t9
|
|
982
|
+
}), $[9] = T1, $[10] = id, $[11] = readOnly, $[12] = t6, $[13] = t7, $[14] = t8, $[15] = t9, $[16] = t10) : t10 = $[16];
|
|
983
|
+
let t11;
|
|
984
|
+
$[17] !== onChange || $[18] !== readOnly || $[19] !== value ? (t11 = isDefined(value) && /* @__PURE__ */ jsx(Button, {
|
|
645
985
|
type: "button",
|
|
646
986
|
mode: "ghost",
|
|
647
987
|
tone: "critical",
|
|
648
|
-
icon: /* @__PURE__ */ jsx(CloseIcon, {
|
|
988
|
+
icon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
649
989
|
text: "Clear",
|
|
650
990
|
disabled: readOnly,
|
|
651
991
|
onClick: () => {
|
|
652
992
|
onChange(unset());
|
|
653
993
|
},
|
|
654
|
-
"aria-label": "Clear the
|
|
655
|
-
}), $[
|
|
656
|
-
let
|
|
657
|
-
$[
|
|
994
|
+
"aria-label": "Clear the selected icon"
|
|
995
|
+
}), $[17] = onChange, $[18] = readOnly, $[19] = value, $[20] = t11) : t11 = $[20];
|
|
996
|
+
let t12;
|
|
997
|
+
$[21] !== handleSelect || $[22] !== icons || $[23] !== id || $[24] !== library || $[25] !== open || $[26] !== selectedName || $[27] !== setOpen || $[28] !== style ? (t12 = open && /* @__PURE__ */ jsx(Picker, {
|
|
658
998
|
id: `${id}-library`,
|
|
659
|
-
|
|
660
|
-
|
|
999
|
+
library,
|
|
1000
|
+
iconStyle: style,
|
|
1001
|
+
allowed: icons,
|
|
1002
|
+
selected: selectedName,
|
|
661
1003
|
onSelect: handleSelect,
|
|
662
1004
|
onClose: () => {
|
|
663
1005
|
setOpen(!1);
|
|
@@ -665,101 +1007,53 @@ function createInput(icons) {
|
|
|
665
1007
|
onClickOutside: () => {
|
|
666
1008
|
setOpen(!1);
|
|
667
1009
|
}
|
|
668
|
-
}), $[
|
|
669
|
-
let
|
|
670
|
-
return $[
|
|
1010
|
+
}), $[21] = handleSelect, $[22] = icons, $[23] = id, $[24] = library, $[25] = open, $[26] = selectedName, $[27] = setOpen, $[28] = style, $[29] = t12) : t12 = $[29];
|
|
1011
|
+
let t13;
|
|
1012
|
+
return $[30] !== T0 || $[31] !== t10 || $[32] !== t11 || $[33] !== t12 ? (t13 = /* @__PURE__ */ jsxs(T0, {
|
|
671
1013
|
gap: 2,
|
|
672
1014
|
children: [
|
|
673
|
-
t9,
|
|
674
1015
|
t10,
|
|
675
|
-
t11
|
|
1016
|
+
t11,
|
|
1017
|
+
t12
|
|
676
1018
|
]
|
|
677
|
-
}), $[
|
|
1019
|
+
}), $[30] = T0, $[31] = t10, $[32] = t11, $[33] = t12, $[34] = t13) : t13 = $[34], t13;
|
|
678
1020
|
}
|
|
679
1021
|
return Input;
|
|
680
1022
|
}
|
|
681
|
-
function SquareDashedIcon(props) {
|
|
682
|
-
let $ = c(14), t0, t1, t10, t11, t2, t3, t4, t5, t6, t7, t8, t9;
|
|
683
|
-
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsx("path", { d: "M5 3a2 2 0 0 0-2 2" }), t1 = /* @__PURE__ */ jsx("path", { d: "M19 3a2 2 0 0 1 2 2" }), t2 = /* @__PURE__ */ jsx("path", { d: "M21 19a2 2 0 0 1-2 2" }), t3 = /* @__PURE__ */ jsx("path", { d: "M5 21a2 2 0 0 1-2-2" }), t4 = /* @__PURE__ */ jsx("path", { d: "M9 3h1" }), t5 = /* @__PURE__ */ jsx("path", { d: "M9 21h1" }), t6 = /* @__PURE__ */ jsx("path", { d: "M14 3h1" }), t7 = /* @__PURE__ */ jsx("path", { d: "M14 21h1" }), t8 = /* @__PURE__ */ jsx("path", { d: "M3 9v1" }), t9 = /* @__PURE__ */ jsx("path", { d: "M21 9v1" }), t10 = /* @__PURE__ */ jsx("path", { d: "M3 14v1" }), t11 = /* @__PURE__ */ jsx("path", { d: "M21 14v1" }), $[0] = t0, $[1] = t1, $[2] = t10, $[3] = t11, $[4] = t2, $[5] = t3, $[6] = t4, $[7] = t5, $[8] = t6, $[9] = t7, $[10] = t8, $[11] = t9) : (t0 = $[0], t1 = $[1], t10 = $[2], t11 = $[3], t2 = $[4], t3 = $[5], t4 = $[6], t5 = $[7], t6 = $[8], t7 = $[9], t8 = $[10], t9 = $[11]);
|
|
684
|
-
let t12;
|
|
685
|
-
return $[12] === props ? t12 = $[13] : (t12 = /* @__PURE__ */ jsxs("svg", {
|
|
686
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
687
|
-
width: 24,
|
|
688
|
-
height: 24,
|
|
689
|
-
viewBox: "0 0 24 24",
|
|
690
|
-
fill: "none",
|
|
691
|
-
stroke: "currentColor",
|
|
692
|
-
strokeWidth: 2,
|
|
693
|
-
strokeLinecap: "round",
|
|
694
|
-
strokeLinejoin: "round",
|
|
695
|
-
...props,
|
|
696
|
-
children: [
|
|
697
|
-
t0,
|
|
698
|
-
t1,
|
|
699
|
-
t2,
|
|
700
|
-
t3,
|
|
701
|
-
t4,
|
|
702
|
-
t5,
|
|
703
|
-
t6,
|
|
704
|
-
t7,
|
|
705
|
-
t8,
|
|
706
|
-
t9,
|
|
707
|
-
t10,
|
|
708
|
-
t11
|
|
709
|
-
]
|
|
710
|
-
}), $[12] = props, $[13] = t12), t12;
|
|
711
|
-
}
|
|
712
|
-
/**
|
|
713
|
-
* Creates a Sanity Studio icon component from an SVG icon.
|
|
714
|
-
*
|
|
715
|
-
* @param icon - The icon component to wrap.
|
|
716
|
-
* @param props - Additional props merged over the default properties a Studio icon is drawn with.
|
|
717
|
-
* @returns A Studio icon component.
|
|
718
|
-
*/
|
|
719
|
-
function createSanityIcon(icon, props) {
|
|
720
|
-
let Icon = icon;
|
|
721
|
-
function SanityIcon() {
|
|
722
|
-
return createElement(Icon, {
|
|
723
|
-
...defaultIconProps,
|
|
724
|
-
...props
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
return SanityIcon;
|
|
728
|
-
}
|
|
729
1023
|
/**
|
|
730
|
-
*
|
|
731
|
-
* rather than one placeholder standing in for every icon alike.
|
|
1024
|
+
* Creates preview media for a stored icon, so each document shows its own icon instead of a placeholder.
|
|
732
1025
|
*
|
|
733
1026
|
* @param value - The stored icon.
|
|
734
1027
|
* @returns The media component, or undefined when nothing readable was stored.
|
|
735
1028
|
* @public
|
|
736
1029
|
*/
|
|
737
1030
|
function createIconPreview(value) {
|
|
738
|
-
let
|
|
739
|
-
if (isDefined(
|
|
1031
|
+
let drawing = resolveIconDrawing(value?.node);
|
|
1032
|
+
if (isDefined(drawing)) return function IconPreview() {
|
|
740
1033
|
return createElement(Drawing, {
|
|
741
|
-
|
|
742
|
-
|
|
1034
|
+
drawing,
|
|
1035
|
+
width: "1em",
|
|
1036
|
+
height: "1em"
|
|
743
1037
|
});
|
|
744
1038
|
};
|
|
745
1039
|
}
|
|
746
1040
|
/**
|
|
747
|
-
* Creates the object type
|
|
748
|
-
* does not name its own.
|
|
1041
|
+
* Creates the icon object type, offering the plugin's icons to fields that don't set their own.
|
|
749
1042
|
*
|
|
750
|
-
* @param
|
|
751
|
-
* @returns
|
|
1043
|
+
* @param config - The plugin configuration.
|
|
1044
|
+
* @returns The icon type.
|
|
752
1045
|
*/
|
|
753
|
-
function createIconType(
|
|
1046
|
+
function createIconType(config) {
|
|
754
1047
|
return defineType({
|
|
755
1048
|
name: iconTypeName,
|
|
756
1049
|
type: "object",
|
|
757
1050
|
icon: createSanityIcon(SquareDashedIcon),
|
|
758
|
-
description: "Icon chosen from
|
|
1051
|
+
description: "Icon chosen from an icon library.",
|
|
759
1052
|
components: {
|
|
760
1053
|
field: Field,
|
|
761
|
-
input: createInput(
|
|
1054
|
+
input: createInput(config)
|
|
762
1055
|
},
|
|
1056
|
+
validation: (rule) => rule.custom((value) => !isDefined(value?.name) || isDefined(value.node) ? !0 : "Select the icon again to save its drawing."),
|
|
763
1057
|
preview: {
|
|
764
1058
|
select: {
|
|
765
1059
|
name: "name",
|
|
@@ -768,7 +1062,7 @@ function createIconType(icons) {
|
|
|
768
1062
|
prepare(selection) {
|
|
769
1063
|
let { name, node } = selection;
|
|
770
1064
|
return {
|
|
771
|
-
title: isDefined(name) ? convertCase(name, "
|
|
1065
|
+
title: isDefined(name) ? convertCase(name, "title") : "No icon",
|
|
772
1066
|
media: createIconPreview({
|
|
773
1067
|
_type: iconTypeName,
|
|
774
1068
|
name,
|
|
@@ -777,34 +1071,43 @@ function createIconType(icons) {
|
|
|
777
1071
|
};
|
|
778
1072
|
}
|
|
779
1073
|
},
|
|
780
|
-
fields: [
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
1074
|
+
fields: [
|
|
1075
|
+
defineField({
|
|
1076
|
+
name: "library",
|
|
1077
|
+
type: "string",
|
|
1078
|
+
description: "Identifier of the library the icon came from."
|
|
1079
|
+
}),
|
|
1080
|
+
defineField({
|
|
1081
|
+
name: "style",
|
|
1082
|
+
type: "string",
|
|
1083
|
+
description: "Identifier of the library style the icon came from."
|
|
1084
|
+
}),
|
|
1085
|
+
defineField({
|
|
1086
|
+
name: "name",
|
|
1087
|
+
type: "string",
|
|
1088
|
+
description: "Name of the icon in its library."
|
|
1089
|
+
}),
|
|
1090
|
+
defineField({
|
|
1091
|
+
name: "node",
|
|
1092
|
+
type: "text",
|
|
1093
|
+
description: "Shapes the icon is drawn from, saved when it's chosen."
|
|
1094
|
+
})
|
|
1095
|
+
]
|
|
789
1096
|
});
|
|
790
1097
|
}
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
name: "@driftime/sanity-plugin-icon",
|
|
796
|
-
schema: { types: [createIconType(icons)] }
|
|
797
|
-
};
|
|
798
|
-
});
|
|
1098
|
+
const plugin = definePlugin((config) => ({
|
|
1099
|
+
name: pluginName,
|
|
1100
|
+
schema: { types: [createIconType(config)] }
|
|
1101
|
+
}));
|
|
799
1102
|
/**
|
|
800
|
-
*
|
|
801
|
-
*
|
|
1103
|
+
* Adds an icon field type to Sanity Studio, with a searchable picker for the installed icon libraries that
|
|
1104
|
+
* stores the chosen icon's drawing.
|
|
802
1105
|
*
|
|
803
|
-
* @param config -
|
|
804
|
-
* @returns
|
|
1106
|
+
* @param config - The plugin configuration.
|
|
1107
|
+
* @returns The plugin.
|
|
805
1108
|
* @public
|
|
806
1109
|
*/
|
|
807
|
-
function iconPlugin(config
|
|
1110
|
+
function iconPlugin(config) {
|
|
808
1111
|
return plugin(config);
|
|
809
1112
|
}
|
|
810
1113
|
export { createIconPreview, iconPlugin };
|