@driftime/sanity-plugin-icon 0.1.0 → 0.3.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 +179 -71
- package/dist/{drawing-Bo0HTICv.js → drawing-BThiR2bN.js} +14 -5
- package/dist/drawing-BThiR2bN.js.map +1 -0
- package/dist/index.d.ts +56 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +550 -342
- package/dist/index.js.map +1 -1
- package/dist/render.d.ts +5 -5
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +1 -2
- package/dist/render.js.map +1 -1
- package/dist/{types-nQUVfUHK.d.ts → types-_D2jGm25.d.ts} +2 -2
- package/dist/types-_D2jGm25.d.ts.map +1 -0
- package/package.json +21 -30
- package/LICENSE +0 -21
- package/dist/drawing-Bo0HTICv.js.map +0 -1
- package/dist/types-nQUVfUHK.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,22 +1,116 @@
|
|
|
1
|
-
import { a as convertCase, i as
|
|
2
|
-
import { FormField, defineField, definePlugin, defineType, set, setIfMissing, unset } from "sanity";
|
|
1
|
+
import { a as convertCase, i as serializeIconNode, n as parseIconNode, o as isDefined, r as resolveIconNode, t as Drawing } from "./drawing-BThiR2bN.js";
|
|
2
|
+
import { ChangeIndicator, FieldActionsProvider, FieldActionsResolver, FormField, defineField, definePlugin, defineType, getPublishedId, set, setIfMissing, unset, useFormValue } from "sanity";
|
|
3
3
|
import { c } from "react/compiler-runtime";
|
|
4
|
-
import {
|
|
4
|
+
import { createElement, useEffect, useRef, useState } from "react";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
import { CloseIcon } from "@sanity/icons/Close";
|
|
6
7
|
import { Box, Button, Dialog, Flex, Grid, Spinner, Stack, Text, TextInput } from "@sanity/ui";
|
|
7
|
-
import { createElement, useEffect, useRef, useState } from "react";
|
|
8
8
|
import { SearchIcon } from "@sanity/icons/Search";
|
|
9
9
|
import { Popover } from "@sanity/ui/popover";
|
|
10
|
+
/**
|
|
11
|
+
* Checks whether a form node holds members of its own, as an object or an array of objects does.
|
|
12
|
+
*
|
|
13
|
+
* @param node - The form node to check.
|
|
14
|
+
* @returns True if the node holds members.
|
|
15
|
+
*/
|
|
16
|
+
function hasMembers(node) {
|
|
17
|
+
return "members" in node;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Gathers the validation reported on a form node and on anything inside it.
|
|
21
|
+
*
|
|
22
|
+
* @param node - The form node to gather validation from.
|
|
23
|
+
* @returns Every validation reported on the node or within it.
|
|
24
|
+
*/
|
|
25
|
+
function collectNodeValidation(node) {
|
|
26
|
+
return [...node.validation, ...hasMembers(node) ? collectMemberValidation(node.members) : []];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Gathers the validation reported anywhere inside a field's members. The form hands a field only what
|
|
30
|
+
* is reported at its own path, which suits a frame drawing its members inline but leaves one that
|
|
31
|
+
* hides them showing nothing they report.
|
|
32
|
+
*
|
|
33
|
+
* @param members - The members to gather validation from.
|
|
34
|
+
* @returns Every validation reported on a member or within one.
|
|
35
|
+
*/
|
|
36
|
+
function collectMemberValidation(members) {
|
|
37
|
+
return members.flatMap((member) => member.kind === "field" ? collectNodeValidation(member.field) : member.kind === "fieldSet" ? collectMemberValidation(member.fieldSet.members) : member.kind === "item" ? collectNodeValidation(member.item) : []);
|
|
38
|
+
}
|
|
10
39
|
function Field(t0) {
|
|
11
|
-
let $ = c(
|
|
12
|
-
|
|
13
|
-
|
|
40
|
+
let $ = c(40), { actions, schemaType, title, description, presence, validation, level, inputId, path, changed, children, inputProps } = t0, t1;
|
|
41
|
+
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t1 = [], $[0] = t1) : t1 = $[0];
|
|
42
|
+
let [headerActions, setHeaderActions] = useState(t1), t2;
|
|
43
|
+
$[1] === Symbol.for("react.memo_cache_sentinel") ? (t2 = ["_id"], $[1] = t2) : t2 = $[1];
|
|
44
|
+
let documentId = useFormValue(t2), fieldValidation, focused, t3;
|
|
45
|
+
if ($[2] !== actions || $[3] !== documentId || $[4] !== inputProps.focused || $[5] !== inputProps.members || $[6] !== path || $[7] !== schemaType || $[8] !== validation) {
|
|
46
|
+
let publishedId = typeof documentId == "string" ? getPublishedId(documentId) : void 0;
|
|
47
|
+
focused = inputProps.focused === !0;
|
|
48
|
+
let t4;
|
|
49
|
+
$[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, {
|
|
50
|
+
actions,
|
|
51
|
+
documentId: publishedId,
|
|
52
|
+
documentType: schemaType.name,
|
|
53
|
+
onActions: setHeaderActions,
|
|
54
|
+
path,
|
|
55
|
+
schemaType
|
|
56
|
+
}), $[2] = actions, $[3] = documentId, $[4] = inputProps.focused, $[5] = inputProps.members, $[6] = path, $[7] = schemaType, $[8] = validation, $[9] = fieldValidation, $[10] = focused, $[11] = t3;
|
|
57
|
+
} else fieldValidation = $[9], focused = $[10], t3 = $[11];
|
|
58
|
+
let t4;
|
|
59
|
+
$[15] !== changed || $[16] !== children || $[17] !== focused || $[18] !== path ? (t4 = /* @__PURE__ */ jsx(ChangeIndicator, {
|
|
60
|
+
path,
|
|
61
|
+
hasFocus: focused,
|
|
62
|
+
isChanged: changed,
|
|
63
|
+
children
|
|
64
|
+
}), $[15] = changed, $[16] = children, $[17] = focused, $[18] = path, $[19] = t4) : t4 = $[19];
|
|
65
|
+
let t5;
|
|
66
|
+
$[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, {
|
|
67
|
+
__unstable_headerActions: headerActions,
|
|
68
|
+
__unstable_presence: presence,
|
|
14
69
|
description,
|
|
15
70
|
inputId,
|
|
16
|
-
|
|
71
|
+
level,
|
|
72
|
+
title,
|
|
73
|
+
validation: fieldValidation,
|
|
74
|
+
deprecated: schemaType.deprecated,
|
|
17
75
|
path,
|
|
18
|
-
|
|
19
|
-
|
|
76
|
+
readOnly: inputProps.readOnly,
|
|
77
|
+
children: t4
|
|
78
|
+
}), $[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];
|
|
79
|
+
let t6;
|
|
80
|
+
$[32] !== focused || $[33] !== headerActions || $[34] !== path || $[35] !== t5 ? (t6 = /* @__PURE__ */ jsx(FieldActionsProvider, {
|
|
81
|
+
actions: headerActions,
|
|
82
|
+
focused,
|
|
83
|
+
path,
|
|
84
|
+
children: t5
|
|
85
|
+
}), $[32] = focused, $[33] = headerActions, $[34] = path, $[35] = t5, $[36] = t6) : t6 = $[36];
|
|
86
|
+
let t7;
|
|
87
|
+
return $[37] !== t3 || $[38] !== t6 ? (t7 = /* @__PURE__ */ jsxs(Fragment, { children: [t3, t6] }), $[37] = t3, $[38] = t6, $[39] = t7) : t7 = $[39], t7;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Properties the plugin's own icons are drawn with. Icons taken from `@sanity/icons` are left alone,
|
|
91
|
+
* since they already carry the sizing and stroke the rest of the Studio uses.
|
|
92
|
+
*/
|
|
93
|
+
const defaultIconProps = {
|
|
94
|
+
width: "1em",
|
|
95
|
+
height: "1em",
|
|
96
|
+
strokeWidth: 1.5
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Creates a Sanity Studio icon component from an SVG icon.
|
|
100
|
+
*
|
|
101
|
+
* @param icon - The icon component to wrap.
|
|
102
|
+
* @param props - Additional props merged over the default properties a Studio icon is drawn with.
|
|
103
|
+
* @returns A Studio icon component.
|
|
104
|
+
*/
|
|
105
|
+
function createSanityIcon(icon, props) {
|
|
106
|
+
let Icon = icon;
|
|
107
|
+
function SanityIcon() {
|
|
108
|
+
return createElement(Icon, {
|
|
109
|
+
...defaultIconProps,
|
|
110
|
+
...props
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return SanityIcon;
|
|
20
114
|
}
|
|
21
115
|
/** Space between rows, in pixels. */
|
|
22
116
|
const gridLayoutStyle = {
|
|
@@ -24,26 +118,30 @@ const gridLayoutStyle = {
|
|
|
24
118
|
rowGap: 4
|
|
25
119
|
};
|
|
26
120
|
function Cell(t0) {
|
|
27
|
-
let $ = c(
|
|
28
|
-
$[0] === t0 ? (focusable = $[1], icon = $[2],
|
|
121
|
+
let $ = c(28), focusable, icon, onHover, onSelect, position, props, selected, total;
|
|
122
|
+
$[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
123
|
let t1 = focusable ? 0 : -1, t2;
|
|
30
|
-
$[
|
|
124
|
+
$[9] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
|
|
31
125
|
width: 40,
|
|
32
126
|
height: 40
|
|
33
|
-
}, $[
|
|
127
|
+
}, $[9] = t2) : t2 = $[9];
|
|
34
128
|
let t3;
|
|
35
|
-
$[
|
|
129
|
+
$[10] === icon.node ? t3 = $[11] : (t3 = /* @__PURE__ */ jsx(Drawing, {
|
|
36
130
|
node: icon.node,
|
|
37
131
|
width: "1.25em",
|
|
38
132
|
height: "1.25em",
|
|
39
133
|
strokeWidth: 1.5
|
|
40
|
-
}), $[
|
|
134
|
+
}), $[10] = icon.node, $[11] = t3);
|
|
41
135
|
let t4;
|
|
42
|
-
$[
|
|
136
|
+
$[12] !== icon || $[13] !== onSelect ? (t4 = () => {
|
|
43
137
|
onSelect(icon);
|
|
44
|
-
}, $[
|
|
138
|
+
}, $[12] = icon, $[13] = onSelect, $[14] = t4) : t4 = $[14];
|
|
45
139
|
let t5;
|
|
46
|
-
|
|
140
|
+
$[15] !== icon || $[16] !== onHover ? (t5 = (event) => {
|
|
141
|
+
onHover(icon, event.currentTarget);
|
|
142
|
+
}, $[15] = icon, $[16] = onHover, $[17] = t5) : t5 = $[17];
|
|
143
|
+
let t6;
|
|
144
|
+
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
145
|
type: "button",
|
|
48
146
|
role: "option",
|
|
49
147
|
"aria-selected": selected,
|
|
@@ -56,23 +154,80 @@ function Cell(t0) {
|
|
|
56
154
|
style: t2,
|
|
57
155
|
icon: t3,
|
|
58
156
|
"aria-label": icon.label,
|
|
59
|
-
"data-icon": icon.name,
|
|
60
157
|
onClick: t4,
|
|
158
|
+
onMouseEnter: t5,
|
|
61
159
|
...props
|
|
62
|
-
}), $[
|
|
160
|
+
}), $[18] = icon.label, $[19] = position, $[20] = props, $[21] = selected, $[22] = t1, $[23] = t3, $[24] = t4, $[25] = t5, $[26] = total, $[27] = t6) : t6 = $[27], t6;
|
|
161
|
+
}
|
|
162
|
+
function Library(t0) {
|
|
163
|
+
let $ = c(29), activeCell, activeIndex, icons, onClearSearch, onHover, onSelect, props, rows, search, selected;
|
|
164
|
+
$[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);
|
|
165
|
+
let { totalRows, firstRow, lastRow } = rows, t1;
|
|
166
|
+
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) {
|
|
167
|
+
let visible = icons.slice(firstRow * 8, lastRow * 8), t2;
|
|
168
|
+
$[24] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
|
|
169
|
+
height: 348,
|
|
170
|
+
overflowY: "auto"
|
|
171
|
+
}, $[24] = t2) : t2 = $[24];
|
|
172
|
+
let t3;
|
|
173
|
+
$[25] !== icons.length || $[26] !== onClearSearch || $[27] !== search ? (t3 = icons.length === 0 && /* @__PURE__ */ jsxs(Flex, {
|
|
174
|
+
align: "center",
|
|
175
|
+
justify: "center",
|
|
176
|
+
direction: "column",
|
|
177
|
+
gap: 3,
|
|
178
|
+
style: { height: 348 },
|
|
179
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
180
|
+
size: 1,
|
|
181
|
+
muted: !0,
|
|
182
|
+
children: `Nothing matches "${search}".`
|
|
183
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
184
|
+
type: "button",
|
|
185
|
+
mode: "ghost",
|
|
186
|
+
text: "Clear search",
|
|
187
|
+
onClick: onClearSearch
|
|
188
|
+
})]
|
|
189
|
+
}), $[25] = icons.length, $[26] = onClearSearch, $[27] = search, $[28] = t3) : t3 = $[28], t1 = /* @__PURE__ */ jsxs(Box, {
|
|
190
|
+
role: "listbox",
|
|
191
|
+
"aria-label": "Icon library",
|
|
192
|
+
style: t2,
|
|
193
|
+
...props,
|
|
194
|
+
children: [t3, icons.length > 0 && /* @__PURE__ */ jsx(Grid, {
|
|
195
|
+
gridTemplateColumns: 8,
|
|
196
|
+
style: {
|
|
197
|
+
...gridLayoutStyle,
|
|
198
|
+
paddingTop: firstRow * 44,
|
|
199
|
+
paddingBottom: (totalRows - lastRow) * 44
|
|
200
|
+
},
|
|
201
|
+
children: visible.map((icon, offset) => {
|
|
202
|
+
let index = firstRow * 8 + offset;
|
|
203
|
+
return /* @__PURE__ */ jsx(Cell, {
|
|
204
|
+
ref: index === activeIndex ? activeCell : void 0,
|
|
205
|
+
icon,
|
|
206
|
+
selected: icon.name === selected,
|
|
207
|
+
focusable: index === activeIndex,
|
|
208
|
+
position: index + 1,
|
|
209
|
+
total: icons.length,
|
|
210
|
+
onSelect,
|
|
211
|
+
onHover
|
|
212
|
+
}, icon.name);
|
|
213
|
+
})
|
|
214
|
+
})]
|
|
215
|
+
}), $[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] = t1;
|
|
216
|
+
} else t1 = $[23];
|
|
217
|
+
return t1;
|
|
63
218
|
}
|
|
64
219
|
function Recent(t0) {
|
|
65
|
-
let $ = c(
|
|
66
|
-
$[0] === t0 ? (icons = $[1], onForget = $[2],
|
|
220
|
+
let $ = c(26), icons, onForget, onHover, onSelect, props, selected;
|
|
221
|
+
$[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);
|
|
67
222
|
let t1;
|
|
68
|
-
$[
|
|
223
|
+
$[7] === Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsx(Text, {
|
|
69
224
|
size: 1,
|
|
70
225
|
weight: "medium",
|
|
71
226
|
muted: !0,
|
|
72
227
|
children: "Recent icons"
|
|
73
|
-
}), $[
|
|
228
|
+
}), $[7] = t1) : t1 = $[7];
|
|
74
229
|
let t2;
|
|
75
|
-
$[
|
|
230
|
+
$[8] === onForget ? t2 = $[9] : (t2 = /* @__PURE__ */ jsxs(Flex, {
|
|
76
231
|
align: "center",
|
|
77
232
|
justify: "space-between",
|
|
78
233
|
gap: 2,
|
|
@@ -83,50 +238,56 @@ function Recent(t0) {
|
|
|
83
238
|
padding: 2,
|
|
84
239
|
text: "Clear",
|
|
85
240
|
onClick: onForget,
|
|
86
|
-
"aria-label": "Forget the recently used icons
|
|
241
|
+
"aria-label": "Forget the recently used icons"
|
|
87
242
|
})]
|
|
88
|
-
}), $[
|
|
243
|
+
}), $[8] = onForget, $[9] = t2);
|
|
89
244
|
let t3;
|
|
90
|
-
if ($[
|
|
245
|
+
if ($[10] !== icons || $[11] !== onHover || $[12] !== onSelect || $[13] !== selected) {
|
|
91
246
|
let t4;
|
|
92
|
-
$[
|
|
247
|
+
$[15] !== icons.length || $[16] !== onHover || $[17] !== onSelect || $[18] !== selected ? (t4 = (icon, index) => /* @__PURE__ */ jsx(Cell, {
|
|
93
248
|
icon,
|
|
94
249
|
selected: icon.name === selected,
|
|
95
250
|
focusable: !0,
|
|
96
251
|
position: index + 1,
|
|
97
252
|
total: icons.length,
|
|
98
|
-
onSelect
|
|
99
|
-
|
|
100
|
-
|
|
253
|
+
onSelect,
|
|
254
|
+
onHover
|
|
255
|
+
}, 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;
|
|
256
|
+
} else t3 = $[14];
|
|
101
257
|
let t4;
|
|
102
|
-
$[
|
|
258
|
+
$[20] === t3 ? t4 = $[21] : (t4 = /* @__PURE__ */ jsx(Grid, {
|
|
103
259
|
role: "listbox",
|
|
104
260
|
"aria-label": "Recent icons",
|
|
105
261
|
gridTemplateColumns: 8,
|
|
106
262
|
style: gridLayoutStyle,
|
|
107
263
|
children: t3
|
|
108
|
-
}), $[
|
|
264
|
+
}), $[20] = t3, $[21] = t4);
|
|
109
265
|
let t5;
|
|
110
|
-
return $[
|
|
266
|
+
return $[22] !== props || $[23] !== t2 || $[24] !== t4 ? (t5 = /* @__PURE__ */ jsxs(Stack, {
|
|
111
267
|
gap: 3,
|
|
112
268
|
...props,
|
|
113
269
|
children: [t2, t4]
|
|
114
|
-
}), $[
|
|
270
|
+
}), $[22] = props, $[23] = t2, $[24] = t4, $[25] = t5) : t5 = $[25], t5;
|
|
115
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* Gap between a tooltip and the cell it points at, given as margins because that is the only lever
|
|
274
|
+
* `@sanity/ui` offers for it. Top only, since a tooltip always sits above.
|
|
275
|
+
*/
|
|
276
|
+
const tooltipMargins = [
|
|
277
|
+
-4,
|
|
278
|
+
0,
|
|
279
|
+
0,
|
|
280
|
+
0
|
|
281
|
+
];
|
|
116
282
|
function Tooltip(t0) {
|
|
117
|
-
let $ = c(
|
|
283
|
+
let $ = c(13), hovered, props;
|
|
118
284
|
$[0] === t0 ? (hovered = $[1], props = $[2]) : ({hovered, ...props} = t0, $[0] = t0, $[1] = hovered, $[2] = props);
|
|
119
285
|
let t1;
|
|
120
286
|
$[3] === hovered ? t1 = $[4] : (t1 = isDefined(hovered), $[3] = hovered, $[4] = t1);
|
|
121
|
-
let t2 = hovered?.element ?? null, t3
|
|
122
|
-
$[5] === Symbol.for("react.memo_cache_sentinel") ? (t3 = [
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
0,
|
|
126
|
-
0
|
|
127
|
-
], t4 = { pointerEvents: "none" }, $[5] = t3, $[6] = t4) : (t3 = $[5], t4 = $[6]);
|
|
128
|
-
let t5;
|
|
129
|
-
$[7] === hovered ? t5 = $[8] : (t5 = isDefined(hovered) && /* @__PURE__ */ jsxs(Stack, {
|
|
287
|
+
let t2 = hovered?.element ?? null, t3;
|
|
288
|
+
$[5] === Symbol.for("react.memo_cache_sentinel") ? (t3 = { pointerEvents: "none" }, $[5] = t3) : t3 = $[5];
|
|
289
|
+
let t4;
|
|
290
|
+
$[6] === hovered ? t4 = $[7] : (t4 = isDefined(hovered) && /* @__PURE__ */ jsxs(Stack, {
|
|
130
291
|
gap: 3,
|
|
131
292
|
style: { maxWidth: "16rem" },
|
|
132
293
|
children: [/* @__PURE__ */ jsx(Text, {
|
|
@@ -138,26 +299,20 @@ function Tooltip(t0) {
|
|
|
138
299
|
muted: !0,
|
|
139
300
|
children: hovered.icon.tags
|
|
140
301
|
})]
|
|
141
|
-
}), $[
|
|
142
|
-
let
|
|
143
|
-
return $[
|
|
302
|
+
}), $[6] = hovered, $[7] = t4);
|
|
303
|
+
let t5;
|
|
304
|
+
return $[8] !== props || $[9] !== t1 || $[10] !== t2 || $[11] !== t4 ? (t5 = /* @__PURE__ */ jsx(Popover, {
|
|
144
305
|
open: t1,
|
|
145
306
|
referenceElement: t2,
|
|
146
307
|
placement: "top",
|
|
147
308
|
portal: !0,
|
|
148
309
|
padding: 3,
|
|
149
|
-
__unstable_margins:
|
|
150
|
-
style:
|
|
151
|
-
content:
|
|
310
|
+
__unstable_margins: tooltipMargins,
|
|
311
|
+
style: t3,
|
|
312
|
+
content: t4,
|
|
152
313
|
...props
|
|
153
|
-
}), $[
|
|
314
|
+
}), $[8] = props, $[9] = t1, $[10] = t2, $[11] = t4, $[12] = t5) : t5 = $[12], t5;
|
|
154
315
|
}
|
|
155
|
-
/** Properties every icon the Studio draws is rendered with. */
|
|
156
|
-
const defaultIconProps = {
|
|
157
|
-
width: "1em",
|
|
158
|
-
height: "1em",
|
|
159
|
-
strokeWidth: 1.5
|
|
160
|
-
};
|
|
161
316
|
/**
|
|
162
317
|
* Flattens text into the form a search compares against, so a hyphenated icon name and a multi-word
|
|
163
318
|
* tag are matched the same way.
|
|
@@ -165,10 +320,26 @@ const defaultIconProps = {
|
|
|
165
320
|
* @param value - The text to flatten.
|
|
166
321
|
* @returns The text in comparable form.
|
|
167
322
|
*/
|
|
168
|
-
function
|
|
323
|
+
function normalizeTerms(value) {
|
|
169
324
|
return value.toLowerCase().replaceAll(/[\s-]+/gu, " ").trim();
|
|
170
325
|
}
|
|
171
326
|
/**
|
|
327
|
+
* Narrows the library to a chosen set of icons, in the order they were named. A name the library does
|
|
328
|
+
* not recognise is skipped, so a set outlives the release it was written against.
|
|
329
|
+
*
|
|
330
|
+
* @param library - Every icon the library offers.
|
|
331
|
+
* @param names - Names of the icons to offer, or nothing to offer them all.
|
|
332
|
+
* @returns The icons on offer.
|
|
333
|
+
*/
|
|
334
|
+
function selectIcons(library, names) {
|
|
335
|
+
if (!isDefined(names)) return library;
|
|
336
|
+
let byName = new Map(library.map((icon) => [icon.name, icon]));
|
|
337
|
+
return [...new Set(names)].flatMap((name) => {
|
|
338
|
+
let icon = byName.get(name);
|
|
339
|
+
return isDefined(icon) ? [icon] : [];
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
172
343
|
* Reads the icon library, pairing each drawing with the terms it can be found by. Both files come
|
|
173
344
|
* from the same release as the icons themselves, so the drawings and their terms never disagree.
|
|
174
345
|
*
|
|
@@ -185,15 +356,17 @@ async function readLibrary() {
|
|
|
185
356
|
label: convertCase(name, "sentence"),
|
|
186
357
|
tags: iconTags.join(", "),
|
|
187
358
|
node,
|
|
188
|
-
terms:
|
|
359
|
+
terms: normalizeTerms([name, ...iconTags].join(" "))
|
|
189
360
|
}];
|
|
190
361
|
});
|
|
191
362
|
}
|
|
192
|
-
/**
|
|
363
|
+
/**
|
|
364
|
+
* The library once asked for, held so every field in a Studio session shares the one request. It is a
|
|
365
|
+
* megabyte of data that never changes within a release, so asking twice only ever costs.
|
|
366
|
+
*/
|
|
193
367
|
let libraryRequest;
|
|
194
368
|
/**
|
|
195
|
-
* Reads the icon library,
|
|
196
|
-
* library is a megabyte of data that never changes within a release, so asking twice only ever costs.
|
|
369
|
+
* Reads the icon library, waiting on whatever request is already under way.
|
|
197
370
|
*
|
|
198
371
|
* @returns Every icon the library offers.
|
|
199
372
|
*/
|
|
@@ -201,8 +374,8 @@ async function requestLibrary() {
|
|
|
201
374
|
return libraryRequest ??= readLibrary(), await libraryRequest;
|
|
202
375
|
}
|
|
203
376
|
/**
|
|
204
|
-
* Reads the icon library
|
|
205
|
-
*
|
|
377
|
+
* Reads the icon library. Callers mount only while a picker is open, so a Studio that never opens one
|
|
378
|
+
* never pays what it costs to read.
|
|
206
379
|
*
|
|
207
380
|
* @returns Every icon the library offers, or undefined while it is still being read.
|
|
208
381
|
*/
|
|
@@ -218,6 +391,46 @@ function useIconLibrary() {
|
|
|
218
391
|
};
|
|
219
392
|
}, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), useEffect(t0, t1), library;
|
|
220
393
|
}
|
|
394
|
+
/**
|
|
395
|
+
* Tracks which icon the cursor rests on, holding a tooltip back until it has settled somewhere.
|
|
396
|
+
*
|
|
397
|
+
* @param scrolling - Whether the grid is currently moving under the cursor.
|
|
398
|
+
* @returns The icon being hovered, alongside ways to follow the cursor and to dismiss it.
|
|
399
|
+
*/
|
|
400
|
+
function useIconTooltip(scrolling) {
|
|
401
|
+
let $ = c(11), [hovered, setHovered] = useState(), hoverStart = useRef(void 0), t0, t1;
|
|
402
|
+
$[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => () => {
|
|
403
|
+
isDefined(hoverStart.current) && clearTimeout(hoverStart.current);
|
|
404
|
+
}, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), useEffect(t0, t1);
|
|
405
|
+
let t2;
|
|
406
|
+
$[2] === hovered ? t2 = $[3] : (t2 = function clearHover() {
|
|
407
|
+
isDefined(hoverStart.current) && clearTimeout(hoverStart.current), isDefined(hovered) && setHovered(void 0);
|
|
408
|
+
}, $[2] = hovered, $[3] = t2);
|
|
409
|
+
let clearHover = t2, t3;
|
|
410
|
+
$[4] !== hovered || $[5] !== scrolling ? (t3 = function handleHover(icon, element) {
|
|
411
|
+
if (!(scrolling || element === hovered?.element)) {
|
|
412
|
+
if (isDefined(hoverStart.current) && clearTimeout(hoverStart.current), isDefined(hovered)) {
|
|
413
|
+
setHovered({
|
|
414
|
+
icon,
|
|
415
|
+
element
|
|
416
|
+
});
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
hoverStart.current = setTimeout(() => {
|
|
420
|
+
setHovered({
|
|
421
|
+
icon,
|
|
422
|
+
element
|
|
423
|
+
});
|
|
424
|
+
}, 200);
|
|
425
|
+
}
|
|
426
|
+
}, $[4] = hovered, $[5] = scrolling, $[6] = t3) : t3 = $[6];
|
|
427
|
+
let handleHover = t3, t4;
|
|
428
|
+
return $[7] !== clearHover || $[8] !== handleHover || $[9] !== hovered ? (t4 = {
|
|
429
|
+
hovered,
|
|
430
|
+
handleHover,
|
|
431
|
+
clearHover
|
|
432
|
+
}, $[7] = clearHover, $[8] = handleHover, $[9] = hovered, $[10] = t4) : t4 = $[10], t4;
|
|
433
|
+
}
|
|
221
434
|
/** Where the icons an author reached for last are kept, in the browser rather than the dataset. */
|
|
222
435
|
const storageKey = "driftime:sanity-plugin-icon:recent";
|
|
223
436
|
/**
|
|
@@ -306,36 +519,59 @@ function getVisibleRows(scrollRow, count) {
|
|
|
306
519
|
lastRow: Math.min(totalRows, firstRow + 8 + 16)
|
|
307
520
|
};
|
|
308
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
* Works out where the scrolling area sits to show a given icon in the middle, for opening on the
|
|
524
|
+
* icon already chosen.
|
|
525
|
+
*
|
|
526
|
+
* @param index - Index of the icon to show.
|
|
527
|
+
* @returns The position to scroll to.
|
|
528
|
+
*/
|
|
529
|
+
function getCenteredScrollTop(index) {
|
|
530
|
+
return Math.max(0, Math.floor(index / 8) * 44 - 174);
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Works out where the scrolling area moves to bring a given icon into view, staying put when the
|
|
534
|
+
* icon already shows. Taken from the index rather than the icon's own cell, since Home and End can
|
|
535
|
+
* land outside the rows that are mounted.
|
|
536
|
+
*
|
|
537
|
+
* @param index - Index of the icon to reveal.
|
|
538
|
+
* @param scrollTop - Position the scrolling area has reached.
|
|
539
|
+
* @returns The position to scroll to.
|
|
540
|
+
*/
|
|
541
|
+
function getRevealedScrollTop(index, scrollTop) {
|
|
542
|
+
let top = Math.floor(index / 8) * 44;
|
|
543
|
+
return top < scrollTop ? top : top + 44 > scrollTop + 348 ? top + 44 - 348 : scrollTop;
|
|
544
|
+
}
|
|
309
545
|
function Picker(t0) {
|
|
310
|
-
let $ = c(
|
|
311
|
-
$[0] === t0 ? (
|
|
312
|
-
let library = useIconLibrary(), { recent, remember, forget } = useRecentIcons(), [search, setSearch] = useState(""), [scrollRow, setScrollRow] = useState(0), [movedIndex, setMovedIndex] = useState(), [
|
|
546
|
+
let $ = c(35), allowed, onSelect, props, selected;
|
|
547
|
+
$[0] === t0 ? (allowed = $[1], onSelect = $[2], props = $[3], selected = $[4]) : ({allowed, selected, onSelect, ...props} = t0, $[0] = t0, $[1] = allowed, $[2] = onSelect, $[3] = props, $[4] = selected);
|
|
548
|
+
let library = useIconLibrary(), icons = selectIcons(library ?? [], allowed), { recent, remember, forget } = useRecentIcons(), [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) => {
|
|
313
549
|
let icon_1 = byName.get(entry);
|
|
314
550
|
return isDefined(icon_1) ? [icon_1] : [];
|
|
315
|
-
}), {
|
|
316
|
-
|
|
551
|
+
}), { 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);
|
|
552
|
+
useEffect(() => {
|
|
317
553
|
let element = scroller.current;
|
|
318
|
-
isDefined(element) && selectedIndex !== -1 && (element.scrollTop =
|
|
319
|
-
},
|
|
554
|
+
isDefined(element) && selectedIndex !== -1 && (element.scrollTop = getCenteredScrollTop(selectedIndex));
|
|
555
|
+
}, [scroller, selectedIndex]);
|
|
556
|
+
let t1, t2;
|
|
557
|
+
$[5] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => () => {
|
|
558
|
+
isDefined(scrollFrame.current) && cancelAnimationFrame(scrollFrame.current), isDefined(scrollStop.current) && clearTimeout(scrollStop.current);
|
|
559
|
+
}, t2 = [], $[5] = t1, $[6] = t2) : (t1 = $[5], t2 = $[6]), useEffect(t1, t2);
|
|
320
560
|
let t3, t4;
|
|
321
|
-
$[7] ===
|
|
322
|
-
|
|
323
|
-
}, t4 = [], $[7] =
|
|
561
|
+
$[7] === activeIndex ? (t3 = $[8], t4 = $[9]) : (t3 = () => {
|
|
562
|
+
focusIndex.current === activeIndex && (focusIndex.current = void 0, isDefined(activeCell.current) && activeCell.current.focus());
|
|
563
|
+
}, t4 = [activeIndex], $[7] = activeIndex, $[8] = t3, $[9] = t4), useEffect(t3, t4);
|
|
324
564
|
let t5;
|
|
325
|
-
$[
|
|
326
|
-
focusActiveCell.current && (focusActiveCell.current = !1, isDefined(activeCell.current) && activeCell.current.focus());
|
|
327
|
-
}, $[9] = t5) : t5 = $[9];
|
|
328
|
-
let t6;
|
|
329
|
-
$[10] === activeIndex ? t6 = $[11] : (t6 = [activeIndex], $[10] = activeIndex, $[11] = t6), useEffect(t5, t6);
|
|
330
|
-
let t7;
|
|
331
|
-
$[12] !== onSelect || $[13] !== remember ? (t7 = function handleSelect(icon_3) {
|
|
565
|
+
$[10] !== onSelect || $[11] !== remember ? (t5 = function handleSelect(icon_3) {
|
|
332
566
|
remember(icon_3.name), onSelect(icon_3);
|
|
333
|
-
}, $[
|
|
334
|
-
let handleSelect =
|
|
335
|
-
$[
|
|
567
|
+
}, $[10] = onSelect, $[11] = remember, $[12] = t5) : t5 = $[12];
|
|
568
|
+
let handleSelect = t5, t6;
|
|
569
|
+
$[13] === Symbol.for("react.memo_cache_sentinel") ? (t6 = function clearSearch() {
|
|
570
|
+
setSearch(""), setMovedIndex(void 0);
|
|
571
|
+
}, $[13] = t6) : t6 = $[13];
|
|
572
|
+
let clearSearch = t6, handleSearch = function handleSearch(event) {
|
|
336
573
|
setSearch(event.currentTarget.value), setMovedIndex(void 0), isDefined(scroller.current) && (scroller.current.scrollTop = 0);
|
|
337
|
-
},
|
|
338
|
-
let handleSearch = t8, selectActive = function selectActive() {
|
|
574
|
+
}, selectActive = function selectActive() {
|
|
339
575
|
let icon_4 = results[activeIndex];
|
|
340
576
|
isDefined(icon_4) && handleSelect(icon_4);
|
|
341
577
|
}, handleSearchKeyDown = function handleSearchKeyDown(event_0) {
|
|
@@ -344,71 +580,83 @@ function Picker(t0) {
|
|
|
344
580
|
return;
|
|
345
581
|
}
|
|
346
582
|
event_0.key === "ArrowDown" && (event_0.preventDefault(), isDefined(activeCell.current) && activeCell.current.focus());
|
|
347
|
-
},
|
|
348
|
-
|
|
349
|
-
isDefined(hoverStart.current) && clearTimeout(hoverStart.current), setHovered(void 0), scrolling || setScrolling(!0), isDefined(scrollStop.current) && clearTimeout(scrollStop.current), scrollStop.current = setTimeout(() => {
|
|
583
|
+
}, handleScroll = function handleScroll() {
|
|
584
|
+
clearHover(), scrolling || setScrolling(!0), isDefined(scrollStop.current) && clearTimeout(scrollStop.current), scrollStop.current = setTimeout(() => {
|
|
350
585
|
setScrolling(!1);
|
|
351
586
|
}, 150), !isDefined(scrollFrame.current) && (scrollFrame.current = requestAnimationFrame(() => {
|
|
352
587
|
scrollFrame.current = void 0;
|
|
353
588
|
let element_0 = scroller.current;
|
|
354
589
|
isDefined(element_0) && setScrollRow(Math.floor(element_0.scrollTop / 44));
|
|
355
590
|
}));
|
|
356
|
-
},
|
|
357
|
-
let handleScroll = t9, handleHover = function handleHover(event_1) {
|
|
358
|
-
if (scrolling) return;
|
|
359
|
-
let target = event_1.target instanceof Element ? event_1.target.closest("[data-icon]") : void 0, cell = target instanceof HTMLElement ? target : void 0;
|
|
360
|
-
if (cell === hovered?.element) return;
|
|
361
|
-
let name = cell?.dataset.icon, icon_5 = isDefined(name) ? byName.get(name) : void 0;
|
|
362
|
-
if (isDefined(hoverStart.current) && clearTimeout(hoverStart.current), !isDefined(icon_5) || !isDefined(cell)) {
|
|
363
|
-
setHovered(void 0);
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
if (isDefined(hovered)) {
|
|
367
|
-
setHovered({
|
|
368
|
-
icon: icon_5,
|
|
369
|
-
element: cell
|
|
370
|
-
});
|
|
371
|
-
return;
|
|
372
|
-
}
|
|
373
|
-
hoverStart.current = setTimeout(() => {
|
|
374
|
-
setHovered({
|
|
375
|
-
icon: icon_5,
|
|
376
|
-
element: cell
|
|
377
|
-
});
|
|
378
|
-
}, 200);
|
|
379
|
-
}, t10;
|
|
380
|
-
$[18] === hovered ? t10 = $[19] : (t10 = function clearHover() {
|
|
381
|
-
isDefined(hoverStart.current) && clearTimeout(hoverStart.current), isDefined(hovered) && setHovered(void 0);
|
|
382
|
-
}, $[18] = hovered, $[19] = t10);
|
|
383
|
-
let clearHover = t10, handleGridKeyDown = function handleGridKeyDown(event_2) {
|
|
591
|
+
}, handleGridKeyDown = function handleGridKeyDown(event_1) {
|
|
384
592
|
let last = results.length - 1;
|
|
385
593
|
if (last < 0) return;
|
|
386
|
-
if (
|
|
387
|
-
|
|
594
|
+
if (event_1.key === "Enter" || event_1.key === " ") {
|
|
595
|
+
event_1.preventDefault(), selectActive();
|
|
388
596
|
return;
|
|
389
597
|
}
|
|
390
|
-
let next = getNextIndex(
|
|
598
|
+
let next = getNextIndex(event_1.key, activeIndex, last);
|
|
391
599
|
if (!isDefined(next)) return;
|
|
392
|
-
|
|
600
|
+
event_1.preventDefault();
|
|
393
601
|
let index = Math.min(Math.max(next, 0), last);
|
|
394
|
-
|
|
602
|
+
focusIndex.current = index, setMovedIndex(index);
|
|
395
603
|
let element_1 = scroller.current;
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
$[
|
|
401
|
-
let t12;
|
|
402
|
-
$[21] === library ? t12 = $[22] : (t12 = isDefined(library), $[21] = library, $[22] = t12);
|
|
403
|
-
let t13;
|
|
404
|
-
$[23] === library ? t13 = $[24] : (t13 = !isDefined(library) && /* @__PURE__ */ jsx(Flex, {
|
|
604
|
+
isDefined(element_1) && (element_1.scrollTop = getRevealedScrollTop(index, element_1.scrollTop));
|
|
605
|
+
}, t7;
|
|
606
|
+
$[14] === Symbol.for("react.memo_cache_sentinel") ? (t7 = /* @__PURE__ */ jsx(SearchIcon, {}), $[14] = t7) : t7 = $[14];
|
|
607
|
+
let t8;
|
|
608
|
+
$[15] === library ? t8 = $[16] : (t8 = !isDefined(library) && /* @__PURE__ */ jsx(Flex, {
|
|
405
609
|
align: "center",
|
|
406
610
|
justify: "center",
|
|
407
611
|
style: { height: 348 },
|
|
408
612
|
children: /* @__PURE__ */ jsx(Spinner, { muted: !0 })
|
|
409
|
-
}), $[
|
|
410
|
-
let
|
|
411
|
-
|
|
613
|
+
}), $[15] = library, $[16] = t8);
|
|
614
|
+
let t9;
|
|
615
|
+
$[17] !== activeIndex || $[18] !== clearHover || $[19] !== clearSearch || $[20] !== handleGridKeyDown || $[21] !== handleHover || $[22] !== handleScroll || $[23] !== handleSelect || $[24] !== icons || $[25] !== library || $[26] !== results || $[27] !== rows || $[28] !== scroller || $[29] !== search || $[30] !== selected ? (t9 = isDefined(library) && /* @__PURE__ */ jsxs(Stack, {
|
|
616
|
+
gap: 3,
|
|
617
|
+
children: [
|
|
618
|
+
/* @__PURE__ */ jsx(Box, {
|
|
619
|
+
paddingY: 2,
|
|
620
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
621
|
+
size: 1,
|
|
622
|
+
weight: "medium",
|
|
623
|
+
muted: !0,
|
|
624
|
+
children: [
|
|
625
|
+
"All icons (",
|
|
626
|
+
results.length.toLocaleString("en-US"),
|
|
627
|
+
")"
|
|
628
|
+
]
|
|
629
|
+
})
|
|
630
|
+
}),
|
|
631
|
+
icons.length === 0 && /* @__PURE__ */ jsx(Flex, {
|
|
632
|
+
align: "center",
|
|
633
|
+
justify: "center",
|
|
634
|
+
style: { height: 348 },
|
|
635
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
636
|
+
size: 1,
|
|
637
|
+
muted: !0,
|
|
638
|
+
children: "No icons are available to choose from."
|
|
639
|
+
})
|
|
640
|
+
}),
|
|
641
|
+
icons.length > 0 && /* @__PURE__ */ jsx(Library, {
|
|
642
|
+
ref: scroller,
|
|
643
|
+
icons: results,
|
|
644
|
+
rows,
|
|
645
|
+
selected,
|
|
646
|
+
activeIndex,
|
|
647
|
+
activeCell,
|
|
648
|
+
search,
|
|
649
|
+
onSelect: handleSelect,
|
|
650
|
+
onHover: handleHover,
|
|
651
|
+
onClearSearch: clearSearch,
|
|
652
|
+
onScroll: handleScroll,
|
|
653
|
+
onMouseLeave: clearHover,
|
|
654
|
+
onKeyDown: handleGridKeyDown
|
|
655
|
+
})
|
|
656
|
+
]
|
|
657
|
+
}), $[17] = activeIndex, $[18] = clearHover, $[19] = clearSearch, $[20] = handleGridKeyDown, $[21] = handleHover, $[22] = handleScroll, $[23] = handleSelect, $[24] = icons, $[25] = library, $[26] = results, $[27] = rows, $[28] = scroller, $[29] = search, $[30] = selected, $[31] = t9) : t9 = $[31];
|
|
658
|
+
let t10 = hovered?.icon.name, t11;
|
|
659
|
+
return $[32] !== hovered || $[33] !== t10 ? (t11 = /* @__PURE__ */ jsx(Tooltip, { hovered }, t10), $[32] = hovered, $[33] = t10, $[34] = t11) : t11 = $[34], /* @__PURE__ */ jsx(Dialog, {
|
|
412
660
|
header: "Select icon",
|
|
413
661
|
width: 1,
|
|
414
662
|
...props,
|
|
@@ -417,94 +665,25 @@ function Picker(t0) {
|
|
|
417
665
|
padding: 4,
|
|
418
666
|
children: [
|
|
419
667
|
/* @__PURE__ */ jsx(TextInput, {
|
|
420
|
-
icon:
|
|
668
|
+
icon: t7,
|
|
421
669
|
placeholder: "Search by name or by what the icon depicts",
|
|
422
670
|
value: search,
|
|
423
671
|
onChange: handleSearch,
|
|
424
672
|
onKeyDown: handleSearchKeyDown,
|
|
425
|
-
disabled: !
|
|
673
|
+
disabled: !isDefined(library) || icons.length === 0,
|
|
426
674
|
"aria-label": "Search the icon library"
|
|
427
675
|
}),
|
|
428
|
-
|
|
676
|
+
t8,
|
|
429
677
|
isDefined(recentIcons) && /* @__PURE__ */ jsx(Recent, {
|
|
430
678
|
icons: recentIcons,
|
|
431
679
|
selected,
|
|
432
680
|
onSelect: handleSelect,
|
|
681
|
+
onHover: handleHover,
|
|
433
682
|
onForget: forget,
|
|
434
|
-
onMouseOver: handleHover,
|
|
435
683
|
onMouseLeave: clearHover
|
|
436
684
|
}),
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
children: [/* @__PURE__ */ jsx(Box, {
|
|
440
|
-
paddingY: 2,
|
|
441
|
-
children: /* @__PURE__ */ jsxs(Text, {
|
|
442
|
-
size: 1,
|
|
443
|
-
weight: "medium",
|
|
444
|
-
muted: !0,
|
|
445
|
-
children: [
|
|
446
|
-
"All icons (",
|
|
447
|
-
results.length.toLocaleString("en-GB"),
|
|
448
|
-
")"
|
|
449
|
-
]
|
|
450
|
-
})
|
|
451
|
-
}), /* @__PURE__ */ jsxs(Box, {
|
|
452
|
-
ref: scroller,
|
|
453
|
-
role: "listbox",
|
|
454
|
-
"aria-label": "Icon library",
|
|
455
|
-
onScroll: handleScroll,
|
|
456
|
-
onMouseOver: handleHover,
|
|
457
|
-
onMouseLeave: clearHover,
|
|
458
|
-
onKeyDown: handleGridKeyDown,
|
|
459
|
-
style: {
|
|
460
|
-
height: 348,
|
|
461
|
-
overflowY: "auto"
|
|
462
|
-
},
|
|
463
|
-
children: [results.length === 0 && /* @__PURE__ */ jsxs(Flex, {
|
|
464
|
-
align: "center",
|
|
465
|
-
justify: "center",
|
|
466
|
-
direction: "column",
|
|
467
|
-
gap: 3,
|
|
468
|
-
style: { height: 348 },
|
|
469
|
-
children: [/* @__PURE__ */ jsxs(Text, {
|
|
470
|
-
size: 1,
|
|
471
|
-
muted: !0,
|
|
472
|
-
children: [
|
|
473
|
-
"Nothing matches “",
|
|
474
|
-
search,
|
|
475
|
-
"”."
|
|
476
|
-
]
|
|
477
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
478
|
-
type: "button",
|
|
479
|
-
mode: "ghost",
|
|
480
|
-
text: "Clear search",
|
|
481
|
-
onClick: () => {
|
|
482
|
-
setSearch(""), setMovedIndex(void 0);
|
|
483
|
-
}
|
|
484
|
-
})]
|
|
485
|
-
}), results.length > 0 && /* @__PURE__ */ jsx(Grid, {
|
|
486
|
-
gridTemplateColumns: 8,
|
|
487
|
-
style: {
|
|
488
|
-
...gridLayoutStyle,
|
|
489
|
-
paddingTop: firstRow * 44,
|
|
490
|
-
paddingBottom: (totalRows - lastRow) * 44
|
|
491
|
-
},
|
|
492
|
-
children: visible.map((icon_6, offset) => {
|
|
493
|
-
let index_0 = firstRow * 8 + offset;
|
|
494
|
-
return /* @__PURE__ */ jsx(Cell, {
|
|
495
|
-
ref: index_0 === activeIndex ? activeCell : void 0,
|
|
496
|
-
icon: icon_6,
|
|
497
|
-
selected: icon_6.name === selected,
|
|
498
|
-
focusable: index_0 === activeIndex,
|
|
499
|
-
position: index_0 + 1,
|
|
500
|
-
total: results.length,
|
|
501
|
-
onSelect: handleSelect
|
|
502
|
-
}, icon_6.name);
|
|
503
|
-
})
|
|
504
|
-
})]
|
|
505
|
-
})]
|
|
506
|
-
}),
|
|
507
|
-
t15
|
|
685
|
+
t9,
|
|
686
|
+
t11
|
|
508
687
|
]
|
|
509
688
|
})
|
|
510
689
|
});
|
|
@@ -512,87 +691,6 @@ function Picker(t0) {
|
|
|
512
691
|
function _temp(icon_0) {
|
|
513
692
|
return [icon_0.name, icon_0];
|
|
514
693
|
}
|
|
515
|
-
/** Type name of the icon object. */
|
|
516
|
-
const iconTypeName = "icon";
|
|
517
|
-
function Input(t0) {
|
|
518
|
-
let $ = c(28), { id, value, onChange, readOnly } = t0, { name, node } = value ?? {}, [open, setOpen] = useState(!1), selectedNode = resolveIconNode(node), selectedLabel = isDefined(name) ? convertCase(name, "sentence") : void 0, t1;
|
|
519
|
-
$[0] !== onChange || $[1] !== setOpen ? (t1 = function handleSelect(icon) {
|
|
520
|
-
onChange([
|
|
521
|
-
setIfMissing({ _type: iconTypeName }),
|
|
522
|
-
set(icon.name, ["name"]),
|
|
523
|
-
set(serialiseIconNode(icon.node), ["node"])
|
|
524
|
-
]), setOpen(!1);
|
|
525
|
-
}, $[0] = onChange, $[1] = setOpen, $[2] = t1) : t1 = $[2];
|
|
526
|
-
let handleSelect = t1, T0 = Flex, T1 = Button, t5 = isDefined(selectedNode) ? /* @__PURE__ */ jsx(Drawing, {
|
|
527
|
-
node: selectedNode,
|
|
528
|
-
...defaultIconProps
|
|
529
|
-
}) : void 0, t6 = selectedLabel ?? "Select icon", t7;
|
|
530
|
-
$[3] === setOpen ? t7 = $[4] : (t7 = () => {
|
|
531
|
-
setOpen(!0);
|
|
532
|
-
}, $[3] = setOpen, $[4] = t7);
|
|
533
|
-
let t8 = isDefined(selectedLabel) ? `${selectedLabel} currently selected` : "Select icon", t9;
|
|
534
|
-
$[5] !== T1 || $[6] !== id || $[7] !== readOnly || $[8] !== t5 || $[9] !== t6 || $[10] !== t7 || $[11] !== t8 ? (t9 = /* @__PURE__ */ jsx(T1, {
|
|
535
|
-
id,
|
|
536
|
-
type: "button",
|
|
537
|
-
mode: "ghost",
|
|
538
|
-
icon: t5,
|
|
539
|
-
text: t6,
|
|
540
|
-
disabled: readOnly,
|
|
541
|
-
onClick: t7,
|
|
542
|
-
"aria-label": t8
|
|
543
|
-
}), $[5] = T1, $[6] = id, $[7] = readOnly, $[8] = t5, $[9] = t6, $[10] = t7, $[11] = t8, $[12] = t9) : t9 = $[12];
|
|
544
|
-
let t10;
|
|
545
|
-
$[13] !== onChange || $[14] !== readOnly || $[15] !== value ? (t10 = isDefined(value) && /* @__PURE__ */ jsx(Button, {
|
|
546
|
-
type: "button",
|
|
547
|
-
mode: "ghost",
|
|
548
|
-
tone: "critical",
|
|
549
|
-
icon: /* @__PURE__ */ jsx(CloseIcon, { ...defaultIconProps }),
|
|
550
|
-
text: "Clear",
|
|
551
|
-
disabled: readOnly,
|
|
552
|
-
onClick: () => {
|
|
553
|
-
onChange(unset());
|
|
554
|
-
},
|
|
555
|
-
"aria-label": "Clear the currently selected icon."
|
|
556
|
-
}), $[13] = onChange, $[14] = readOnly, $[15] = value, $[16] = t10) : t10 = $[16];
|
|
557
|
-
let t11;
|
|
558
|
-
$[17] !== handleSelect || $[18] !== id || $[19] !== name || $[20] !== open || $[21] !== setOpen ? (t11 = open && /* @__PURE__ */ jsx(Picker, {
|
|
559
|
-
id: `${id}-library`,
|
|
560
|
-
selected: name,
|
|
561
|
-
onSelect: handleSelect,
|
|
562
|
-
onClose: () => {
|
|
563
|
-
setOpen(!1);
|
|
564
|
-
},
|
|
565
|
-
onClickOutside: () => {
|
|
566
|
-
setOpen(!1);
|
|
567
|
-
}
|
|
568
|
-
}), $[17] = handleSelect, $[18] = id, $[19] = name, $[20] = open, $[21] = setOpen, $[22] = t11) : t11 = $[22];
|
|
569
|
-
let t12;
|
|
570
|
-
return $[23] !== T0 || $[24] !== t10 || $[25] !== t11 || $[26] !== t9 ? (t12 = /* @__PURE__ */ jsxs(T0, {
|
|
571
|
-
gap: 2,
|
|
572
|
-
children: [
|
|
573
|
-
t9,
|
|
574
|
-
t10,
|
|
575
|
-
t11
|
|
576
|
-
]
|
|
577
|
-
}), $[23] = T0, $[24] = t10, $[25] = t11, $[26] = t9, $[27] = t12) : t12 = $[27], t12;
|
|
578
|
-
}
|
|
579
|
-
/**
|
|
580
|
-
* Builds the media a stored icon previews with, so a document lists the drawing an author chose
|
|
581
|
-
* rather than one placeholder standing in for every icon alike.
|
|
582
|
-
*
|
|
583
|
-
* @param value - The stored icon.
|
|
584
|
-
* @returns The media component, or undefined when nothing readable was stored.
|
|
585
|
-
* @public
|
|
586
|
-
*/
|
|
587
|
-
function createIconPreview(value) {
|
|
588
|
-
let node = resolveIconNode(value?.node);
|
|
589
|
-
if (isDefined(node)) return function IconPreview() {
|
|
590
|
-
return /* @__PURE__ */ jsx(Drawing, {
|
|
591
|
-
node,
|
|
592
|
-
...defaultIconProps
|
|
593
|
-
});
|
|
594
|
-
};
|
|
595
|
-
}
|
|
596
694
|
function SquareDashedIcon(props) {
|
|
597
695
|
let $ = c(14), t0, t1, t10, t11, t2, t3, t4, t5, t6, t7, t8, t9;
|
|
598
696
|
$[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]);
|
|
@@ -625,61 +723,171 @@ function SquareDashedIcon(props) {
|
|
|
625
723
|
}), $[12] = props, $[13] = t12), t12;
|
|
626
724
|
}
|
|
627
725
|
/**
|
|
628
|
-
*
|
|
726
|
+
* Settles what an icon field offers. The list says what is on and replaces whatever the plugin was
|
|
727
|
+
* given, so one line tells you the whole answer.
|
|
629
728
|
*
|
|
630
|
-
* @param
|
|
631
|
-
* @param
|
|
632
|
-
* @returns
|
|
729
|
+
* @param options - Options the field itself was given.
|
|
730
|
+
* @param config - Configuration the plugin was given.
|
|
731
|
+
* @returns The settings the field runs on.
|
|
633
732
|
*/
|
|
634
|
-
function
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
733
|
+
function resolveIconOptions(options, config) {
|
|
734
|
+
return { icons: options?.icons ?? config.icons };
|
|
735
|
+
}
|
|
736
|
+
/** Type name of the icon object. */
|
|
737
|
+
const iconTypeName = "icon";
|
|
738
|
+
/**
|
|
739
|
+
* Creates the input an icon field is drawn with, holding the configuration the plugin was given so a
|
|
740
|
+
* field naming its own icons replaces them rather than adding to them.
|
|
741
|
+
*
|
|
742
|
+
* @param config - Configuration every field falls back to.
|
|
743
|
+
* @returns The input component.
|
|
744
|
+
*/
|
|
745
|
+
function createInput(config) {
|
|
746
|
+
function Input(t0) {
|
|
747
|
+
let $ = c(31), { id, schemaType, value, onChange, readOnly } = t0, { name, node } = value ?? {}, [open, setOpen] = useState(!1), t1;
|
|
748
|
+
$[0] === schemaType.options ? t1 = $[1] : (t1 = resolveIconOptions(schemaType.options, config), $[0] = schemaType.options, $[1] = t1);
|
|
749
|
+
let { icons } = t1, selectedNode = resolveIconNode(node), selectedLabel = isDefined(name) ? convertCase(name, "sentence") : void 0, t2;
|
|
750
|
+
$[2] !== onChange || $[3] !== setOpen ? (t2 = function handleSelect(icon) {
|
|
751
|
+
onChange([
|
|
752
|
+
setIfMissing({ _type: iconTypeName }),
|
|
753
|
+
set(icon.name, ["name"]),
|
|
754
|
+
set(serializeIconNode(icon.node), ["node"])
|
|
755
|
+
]), setOpen(!1);
|
|
756
|
+
}, $[2] = onChange, $[3] = setOpen, $[4] = t2) : t2 = $[4];
|
|
757
|
+
let handleSelect = t2, T0 = Flex, T1 = Button, t6 = isDefined(selectedNode) ? /* @__PURE__ */ jsx(Drawing, {
|
|
758
|
+
node: selectedNode,
|
|
759
|
+
...defaultIconProps
|
|
760
|
+
}) : /* @__PURE__ */ jsx(SquareDashedIcon, { ...defaultIconProps }), t7 = selectedLabel ?? "Select icon", t8;
|
|
761
|
+
$[5] === setOpen ? t8 = $[6] : (t8 = () => {
|
|
762
|
+
setOpen(!0);
|
|
763
|
+
}, $[5] = setOpen, $[6] = t8);
|
|
764
|
+
let t9 = isDefined(selectedLabel) ? `${selectedLabel} currently selected` : "Select icon", t10;
|
|
765
|
+
$[7] !== T1 || $[8] !== id || $[9] !== readOnly || $[10] !== t6 || $[11] !== t7 || $[12] !== t8 || $[13] !== t9 ? (t10 = /* @__PURE__ */ jsx(T1, {
|
|
766
|
+
id,
|
|
767
|
+
type: "button",
|
|
768
|
+
mode: "ghost",
|
|
769
|
+
icon: t6,
|
|
770
|
+
text: t7,
|
|
771
|
+
disabled: readOnly,
|
|
772
|
+
onClick: t8,
|
|
773
|
+
"aria-label": t9
|
|
774
|
+
}), $[7] = T1, $[8] = id, $[9] = readOnly, $[10] = t6, $[11] = t7, $[12] = t8, $[13] = t9, $[14] = t10) : t10 = $[14];
|
|
775
|
+
let t11;
|
|
776
|
+
$[15] !== onChange || $[16] !== readOnly || $[17] !== value ? (t11 = isDefined(value) && /* @__PURE__ */ jsx(Button, {
|
|
777
|
+
type: "button",
|
|
778
|
+
mode: "ghost",
|
|
779
|
+
tone: "critical",
|
|
780
|
+
icon: /* @__PURE__ */ jsx(CloseIcon, {}),
|
|
781
|
+
text: "Clear",
|
|
782
|
+
disabled: readOnly,
|
|
783
|
+
onClick: () => {
|
|
784
|
+
onChange(unset());
|
|
785
|
+
},
|
|
786
|
+
"aria-label": "Clear the currently selected icon"
|
|
787
|
+
}), $[15] = onChange, $[16] = readOnly, $[17] = value, $[18] = t11) : t11 = $[18];
|
|
788
|
+
let t12;
|
|
789
|
+
$[19] !== handleSelect || $[20] !== icons || $[21] !== id || $[22] !== name || $[23] !== open || $[24] !== setOpen ? (t12 = open && /* @__PURE__ */ jsx(Picker, {
|
|
790
|
+
id: `${id}-library`,
|
|
791
|
+
allowed: icons,
|
|
792
|
+
selected: name,
|
|
793
|
+
onSelect: handleSelect,
|
|
794
|
+
onClose: () => {
|
|
795
|
+
setOpen(!1);
|
|
796
|
+
},
|
|
797
|
+
onClickOutside: () => {
|
|
798
|
+
setOpen(!1);
|
|
799
|
+
}
|
|
800
|
+
}), $[19] = handleSelect, $[20] = icons, $[21] = id, $[22] = name, $[23] = open, $[24] = setOpen, $[25] = t12) : t12 = $[25];
|
|
801
|
+
let t13;
|
|
802
|
+
return $[26] !== T0 || $[27] !== t10 || $[28] !== t11 || $[29] !== t12 ? (t13 = /* @__PURE__ */ jsxs(T0, {
|
|
803
|
+
gap: 2,
|
|
804
|
+
children: [
|
|
805
|
+
t10,
|
|
806
|
+
t11,
|
|
807
|
+
t12
|
|
808
|
+
]
|
|
809
|
+
}), $[26] = T0, $[27] = t10, $[28] = t11, $[29] = t12, $[30] = t13) : t13 = $[30], t13;
|
|
641
810
|
}
|
|
642
|
-
return
|
|
811
|
+
return Input;
|
|
643
812
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
node
|
|
813
|
+
/**
|
|
814
|
+
* Builds the media a stored icon previews with, so a document lists the drawing an author chose
|
|
815
|
+
* rather than one placeholder standing in for every icon alike.
|
|
816
|
+
*
|
|
817
|
+
* @param value - The stored icon.
|
|
818
|
+
* @returns The media component, or undefined when nothing readable was stored.
|
|
819
|
+
* @public
|
|
820
|
+
*/
|
|
821
|
+
function createIconPreview(value) {
|
|
822
|
+
let node = resolveIconNode(value?.node);
|
|
823
|
+
if (isDefined(node)) return function IconPreview() {
|
|
824
|
+
return createElement(Drawing, {
|
|
825
|
+
node,
|
|
826
|
+
...defaultIconProps
|
|
827
|
+
});
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Creates the object type an icon is stored as, offering the icons it is given to every field that
|
|
832
|
+
* does not name its own.
|
|
833
|
+
*
|
|
834
|
+
* @param config - Configuration every field falls back to.
|
|
835
|
+
* @returns An object type definition for a stored icon.
|
|
836
|
+
*/
|
|
837
|
+
function createIconType(config) {
|
|
838
|
+
return defineType({
|
|
839
|
+
name: iconTypeName,
|
|
840
|
+
type: "object",
|
|
841
|
+
icon: createSanityIcon(SquareDashedIcon),
|
|
842
|
+
description: "Icon chosen from the Lucide library.",
|
|
843
|
+
components: {
|
|
844
|
+
field: Field,
|
|
845
|
+
input: createInput(config)
|
|
657
846
|
},
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
847
|
+
validation: (rule) => rule.custom((value) => !isDefined(value?.name) || isDefined(value.node) ? !0 : "Select the icon again so its drawing is stored."),
|
|
848
|
+
preview: {
|
|
849
|
+
select: {
|
|
850
|
+
name: "name",
|
|
851
|
+
node: "node"
|
|
852
|
+
},
|
|
853
|
+
prepare(selection) {
|
|
854
|
+
let { name, node } = selection;
|
|
855
|
+
return {
|
|
856
|
+
title: isDefined(name) ? convertCase(name, "sentence") : "No icon",
|
|
857
|
+
media: createIconPreview({
|
|
858
|
+
_type: iconTypeName,
|
|
859
|
+
name,
|
|
860
|
+
node
|
|
861
|
+
})
|
|
862
|
+
};
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
fields: [defineField({
|
|
866
|
+
name: "name",
|
|
867
|
+
type: "string",
|
|
868
|
+
description: "Name of the chosen icon in the library it was taken from."
|
|
869
|
+
}), defineField({
|
|
870
|
+
name: "node",
|
|
871
|
+
type: "text",
|
|
872
|
+
description: "Shapes the icon is drawn from, written when the icon is chosen."
|
|
873
|
+
})]
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
const plugin = definePlugin((config) => ({
|
|
680
877
|
name: "@driftime/sanity-plugin-icon",
|
|
681
|
-
schema: { types: [
|
|
682
|
-
});
|
|
878
|
+
schema: { types: [createIconType(config)] }
|
|
879
|
+
}));
|
|
880
|
+
/**
|
|
881
|
+
* Creates the icon field type for Sanity Studio, offering the Lucide library through a searchable
|
|
882
|
+
* picker and storing the chosen drawing ready to render.
|
|
883
|
+
*
|
|
884
|
+
* @param config - Plugin configuration.
|
|
885
|
+
* @returns Sanity plugin definition.
|
|
886
|
+
* @public
|
|
887
|
+
*/
|
|
888
|
+
function iconPlugin(config = {}) {
|
|
889
|
+
return plugin(config);
|
|
890
|
+
}
|
|
683
891
|
export { createIconPreview, iconPlugin };
|
|
684
892
|
|
|
685
893
|
//# sourceMappingURL=index.js.map
|