@driftime/sanity-plugin-icon 0.2.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/dist/index.js CHANGED
@@ -1,22 +1,116 @@
1
- import { a as convertCase, i as serialiseIconNode, n as parseIconNode, o as isDefined, r as resolveIconNode, t as Drawing } from "./drawing-Bo0HTICv.js";
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 { jsx, jsxs } from "react/jsx-runtime";
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(7), { title, description, inputId, validation, path, children } = t0, t1;
12
- return $[0] !== children || $[1] !== description || $[2] !== inputId || $[3] !== path || $[4] !== title || $[5] !== validation ? (t1 = /* @__PURE__ */ jsx(FormField, {
13
- title,
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
- validation,
71
+ level,
72
+ title,
73
+ validation: fieldValidation,
74
+ deprecated: schemaType.deprecated,
17
75
  path,
18
- children
19
- }), $[0] = children, $[1] = description, $[2] = inputId, $[3] = path, $[4] = title, $[5] = validation, $[6] = t1) : t1 = $[6], t1;
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(24), focusable, icon, onSelect, position, props, selected, total;
28
- $[0] === t0 ? (focusable = $[1], icon = $[2], onSelect = $[3], position = $[4], props = $[5], selected = $[6], total = $[7]) : ({icon, selected, focusable, position, total, onSelect, ...props} = t0, $[0] = t0, $[1] = focusable, $[2] = icon, $[3] = onSelect, $[4] = position, $[5] = props, $[6] = selected, $[7] = total);
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
- $[8] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
124
+ $[9] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
31
125
  width: 40,
32
126
  height: 40
33
- }, $[8] = t2) : t2 = $[8];
127
+ }, $[9] = t2) : t2 = $[9];
34
128
  let t3;
35
- $[9] === icon.node ? t3 = $[10] : (t3 = /* @__PURE__ */ jsx(Drawing, {
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
- }), $[9] = icon.node, $[10] = t3);
134
+ }), $[10] = icon.node, $[11] = t3);
41
135
  let t4;
42
- $[11] !== icon || $[12] !== onSelect ? (t4 = () => {
136
+ $[12] !== icon || $[13] !== onSelect ? (t4 = () => {
43
137
  onSelect(icon);
44
- }, $[11] = icon, $[12] = onSelect, $[13] = t4) : t4 = $[13];
138
+ }, $[12] = icon, $[13] = onSelect, $[14] = t4) : t4 = $[14];
45
139
  let t5;
46
- return $[14] !== icon.label || $[15] !== icon.name || $[16] !== position || $[17] !== props || $[18] !== selected || $[19] !== t1 || $[20] !== t3 || $[21] !== t4 || $[22] !== total ? (t5 = /* @__PURE__ */ jsx(Button, {
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,43 +154,39 @@ 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
- }), $[14] = icon.label, $[15] = icon.name, $[16] = position, $[17] = props, $[18] = selected, $[19] = t1, $[20] = t3, $[21] = t4, $[22] = total, $[23] = t5) : t5 = $[23], t5;
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;
63
161
  }
64
162
  function Library(t0) {
65
- let $ = c(27), activeCell, activeIndex, icons, onClearSearch, onSelect, props, rows, search, selected;
66
- $[0] === t0 ? (activeCell = $[1], activeIndex = $[2], icons = $[3], onClearSearch = $[4], onSelect = $[5], props = $[6], rows = $[7], search = $[8], selected = $[9]) : ({icons, rows, selected, activeIndex, activeCell, search, onSelect, onClearSearch, ...props} = t0, $[0] = t0, $[1] = activeCell, $[2] = activeIndex, $[3] = icons, $[4] = onClearSearch, $[5] = onSelect, $[6] = props, $[7] = rows, $[8] = search, $[9] = selected);
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);
67
165
  let { totalRows, firstRow, lastRow } = rows, t1;
68
- if ($[10] !== activeCell || $[11] !== activeIndex || $[12] !== firstRow || $[13] !== icons || $[14] !== lastRow || $[15] !== onClearSearch || $[16] !== onSelect || $[17] !== props || $[18] !== search || $[19] !== selected || $[20] !== totalRows) {
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) {
69
167
  let visible = icons.slice(firstRow * 8, lastRow * 8), t2;
70
- $[22] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
168
+ $[24] === Symbol.for("react.memo_cache_sentinel") ? (t2 = {
71
169
  height: 348,
72
170
  overflowY: "auto"
73
- }, $[22] = t2) : t2 = $[22];
171
+ }, $[24] = t2) : t2 = $[24];
74
172
  let t3;
75
- $[23] !== icons.length || $[24] !== onClearSearch || $[25] !== search ? (t3 = icons.length === 0 && /* @__PURE__ */ jsxs(Flex, {
173
+ $[25] !== icons.length || $[26] !== onClearSearch || $[27] !== search ? (t3 = icons.length === 0 && /* @__PURE__ */ jsxs(Flex, {
76
174
  align: "center",
77
175
  justify: "center",
78
176
  direction: "column",
79
177
  gap: 3,
80
178
  style: { height: 348 },
81
- children: [/* @__PURE__ */ jsxs(Text, {
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
- }), $[23] = icons.length, $[24] = onClearSearch, $[25] = search, $[26] = t3) : t3 = $[26], t1 = /* @__PURE__ */ jsxs(Box, {
189
+ }), $[25] = icons.length, $[26] = onClearSearch, $[27] = search, $[28] = t3) : t3 = $[28], t1 = /* @__PURE__ */ jsxs(Box, {
96
190
  role: "listbox",
97
191
  "aria-label": "Icon library",
98
192
  style: t2,
@@ -113,26 +207,27 @@ function Library(t0) {
113
207
  focusable: index === activeIndex,
114
208
  position: index + 1,
115
209
  total: icons.length,
116
- onSelect
210
+ onSelect,
211
+ onHover
117
212
  }, icon.name);
118
213
  })
119
214
  })]
120
- }), $[10] = activeCell, $[11] = activeIndex, $[12] = firstRow, $[13] = icons, $[14] = lastRow, $[15] = onClearSearch, $[16] = onSelect, $[17] = props, $[18] = search, $[19] = selected, $[20] = totalRows, $[21] = t1;
121
- } else t1 = $[21];
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];
122
217
  return t1;
123
218
  }
124
219
  function Recent(t0) {
125
- let $ = c(23), icons, onForget, onSelect, props, selected;
126
- $[0] === t0 ? (icons = $[1], onForget = $[2], onSelect = $[3], props = $[4], selected = $[5]) : ({icons, selected, onSelect, onForget, ...props} = t0, $[0] = t0, $[1] = icons, $[2] = onForget, $[3] = onSelect, $[4] = props, $[5] = selected);
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);
127
222
  let t1;
128
- $[6] === Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsx(Text, {
223
+ $[7] === Symbol.for("react.memo_cache_sentinel") ? (t1 = /* @__PURE__ */ jsx(Text, {
129
224
  size: 1,
130
225
  weight: "medium",
131
226
  muted: !0,
132
227
  children: "Recent icons"
133
- }), $[6] = t1) : t1 = $[6];
228
+ }), $[7] = t1) : t1 = $[7];
134
229
  let t2;
135
- $[7] === onForget ? t2 = $[8] : (t2 = /* @__PURE__ */ jsxs(Flex, {
230
+ $[8] === onForget ? t2 = $[9] : (t2 = /* @__PURE__ */ jsxs(Flex, {
136
231
  align: "center",
137
232
  justify: "space-between",
138
233
  gap: 2,
@@ -143,50 +238,56 @@ function Recent(t0) {
143
238
  padding: 2,
144
239
  text: "Clear",
145
240
  onClick: onForget,
146
- "aria-label": "Forget the recently used icons."
241
+ "aria-label": "Forget the recently used icons"
147
242
  })]
148
- }), $[7] = onForget, $[8] = t2);
243
+ }), $[8] = onForget, $[9] = t2);
149
244
  let t3;
150
- if ($[9] !== icons || $[10] !== onSelect || $[11] !== selected) {
245
+ if ($[10] !== icons || $[11] !== onHover || $[12] !== onSelect || $[13] !== selected) {
151
246
  let t4;
152
- $[13] !== icons.length || $[14] !== onSelect || $[15] !== selected ? (t4 = (icon, index) => /* @__PURE__ */ jsx(Cell, {
247
+ $[15] !== icons.length || $[16] !== onHover || $[17] !== onSelect || $[18] !== selected ? (t4 = (icon, index) => /* @__PURE__ */ jsx(Cell, {
153
248
  icon,
154
249
  selected: icon.name === selected,
155
250
  focusable: !0,
156
251
  position: index + 1,
157
252
  total: icons.length,
158
- onSelect
159
- }, icon.name), $[13] = icons.length, $[14] = onSelect, $[15] = selected, $[16] = t4) : t4 = $[16], t3 = icons.map(t4), $[9] = icons, $[10] = onSelect, $[11] = selected, $[12] = t3;
160
- } else t3 = $[12];
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];
161
257
  let t4;
162
- $[17] === t3 ? t4 = $[18] : (t4 = /* @__PURE__ */ jsx(Grid, {
258
+ $[20] === t3 ? t4 = $[21] : (t4 = /* @__PURE__ */ jsx(Grid, {
163
259
  role: "listbox",
164
260
  "aria-label": "Recent icons",
165
261
  gridTemplateColumns: 8,
166
262
  style: gridLayoutStyle,
167
263
  children: t3
168
- }), $[17] = t3, $[18] = t4);
264
+ }), $[20] = t3, $[21] = t4);
169
265
  let t5;
170
- return $[19] !== props || $[20] !== t2 || $[21] !== t4 ? (t5 = /* @__PURE__ */ jsxs(Stack, {
266
+ return $[22] !== props || $[23] !== t2 || $[24] !== t4 ? (t5 = /* @__PURE__ */ jsxs(Stack, {
171
267
  gap: 3,
172
268
  ...props,
173
269
  children: [t2, t4]
174
- }), $[19] = props, $[20] = t2, $[21] = t4, $[22] = t5) : t5 = $[22], t5;
270
+ }), $[22] = props, $[23] = t2, $[24] = t4, $[25] = t5) : t5 = $[25], t5;
175
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
+ ];
176
282
  function Tooltip(t0) {
177
- let $ = c(14), hovered, props;
283
+ let $ = c(13), hovered, props;
178
284
  $[0] === t0 ? (hovered = $[1], props = $[2]) : ({hovered, ...props} = t0, $[0] = t0, $[1] = hovered, $[2] = props);
179
285
  let t1;
180
286
  $[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, {
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, {
190
291
  gap: 3,
191
292
  style: { maxWidth: "16rem" },
192
293
  children: [/* @__PURE__ */ jsx(Text, {
@@ -198,26 +299,20 @@ function Tooltip(t0) {
198
299
  muted: !0,
199
300
  children: hovered.icon.tags
200
301
  })]
201
- }), $[7] = hovered, $[8] = t5);
202
- let t6;
203
- return $[9] !== props || $[10] !== t1 || $[11] !== t2 || $[12] !== t5 ? (t6 = /* @__PURE__ */ jsx(Popover, {
302
+ }), $[6] = hovered, $[7] = t4);
303
+ let t5;
304
+ return $[8] !== props || $[9] !== t1 || $[10] !== t2 || $[11] !== t4 ? (t5 = /* @__PURE__ */ jsx(Popover, {
204
305
  open: t1,
205
306
  referenceElement: t2,
206
307
  placement: "top",
207
308
  portal: !0,
208
309
  padding: 3,
209
- __unstable_margins: t3,
210
- style: t4,
211
- content: t5,
310
+ __unstable_margins: tooltipMargins,
311
+ style: t3,
312
+ content: t4,
212
313
  ...props
213
- }), $[9] = props, $[10] = t1, $[11] = t2, $[12] = t5, $[13] = t6) : t6 = $[13], t6;
314
+ }), $[8] = props, $[9] = t1, $[10] = t2, $[11] = t4, $[12] = t5) : t5 = $[12], t5;
214
315
  }
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
316
  /**
222
317
  * Flattens text into the form a search compares against, so a hyphenated icon name and a multi-word
223
318
  * tag are matched the same way.
@@ -225,7 +320,7 @@ const defaultIconProps = {
225
320
  * @param value - The text to flatten.
226
321
  * @returns The text in comparable form.
227
322
  */
228
- function normaliseTerms(value) {
323
+ function normalizeTerms(value) {
229
324
  return value.toLowerCase().replaceAll(/[\s-]+/gu, " ").trim();
230
325
  }
231
326
  /**
@@ -261,15 +356,17 @@ async function readLibrary() {
261
356
  label: convertCase(name, "sentence"),
262
357
  tags: iconTags.join(", "),
263
358
  node,
264
- terms: normaliseTerms([name, ...iconTags].join(" "))
359
+ terms: normalizeTerms([name, ...iconTags].join(" "))
265
360
  }];
266
361
  });
267
362
  }
268
- /** The library once asked for, held so every field in a Studio session shares the one request. */
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
+ */
269
367
  let libraryRequest;
270
368
  /**
271
- * Reads the icon library, sharing a single request across every field opened in the session. The
272
- * 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.
273
370
  *
274
371
  * @returns Every icon the library offers.
275
372
  */
@@ -277,8 +374,8 @@ async function requestLibrary() {
277
374
  return libraryRequest ??= readLibrary(), await libraryRequest;
278
375
  }
279
376
  /**
280
- * Reads the icon library, sharing one request with every other field in the session. Callers mount
281
- * only while a picker is open, so a Studio that never opens one never pays the megabyte it costs.
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.
282
379
  *
283
380
  * @returns Every icon the library offers, or undefined while it is still being read.
284
381
  */
@@ -297,12 +394,11 @@ function useIconLibrary() {
297
394
  /**
298
395
  * Tracks which icon the cursor rests on, holding a tooltip back until it has settled somewhere.
299
396
  *
300
- * @param byName - Every icon the library offers, keyed by the name it goes by.
301
397
  * @param scrolling - Whether the grid is currently moving under the cursor.
302
398
  * @returns The icon being hovered, alongside ways to follow the cursor and to dismiss it.
303
399
  */
304
- function useIconTooltip(byName, scrolling) {
305
- let $ = c(12), [hovered, setHovered] = useState(), hoverStart = useRef(void 0), t0, t1;
400
+ function useIconTooltip(scrolling) {
401
+ let $ = c(11), [hovered, setHovered] = useState(), hoverStart = useRef(void 0), t0, t1;
306
402
  $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => () => {
307
403
  isDefined(hoverStart.current) && clearTimeout(hoverStart.current);
308
404
  }, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), useEffect(t0, t1);
@@ -311,35 +407,29 @@ function useIconTooltip(byName, scrolling) {
311
407
  isDefined(hoverStart.current) && clearTimeout(hoverStart.current), isDefined(hovered) && setHovered(void 0);
312
408
  }, $[2] = hovered, $[3] = t2);
313
409
  let clearHover = t2, t3;
314
- $[4] !== byName || $[5] !== hovered || $[6] !== scrolling ? (t3 = function handleHover(event) {
315
- if (scrolling) return;
316
- let target = event.target instanceof Element ? event.target.closest("[data-icon]") : void 0, cell = target instanceof HTMLElement ? target : void 0;
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({
325
- icon,
326
- element: cell
327
- });
328
- return;
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);
329
425
  }
330
- hoverStart.current = setTimeout(() => {
331
- setHovered({
332
- icon,
333
- element: cell
334
- });
335
- }, 200);
336
- }, $[4] = byName, $[5] = hovered, $[6] = scrolling, $[7] = t3) : t3 = $[7];
426
+ }, $[4] = hovered, $[5] = scrolling, $[6] = t3) : t3 = $[6];
337
427
  let handleHover = t3, t4;
338
- return $[8] !== clearHover || $[9] !== handleHover || $[10] !== hovered ? (t4 = {
428
+ return $[7] !== clearHover || $[8] !== handleHover || $[9] !== hovered ? (t4 = {
339
429
  hovered,
340
430
  handleHover,
341
431
  clearHover
342
- }, $[8] = clearHover, $[9] = handleHover, $[10] = hovered, $[11] = t4) : t4 = $[11], t4;
432
+ }, $[7] = clearHover, $[8] = handleHover, $[9] = hovered, $[10] = t4) : t4 = $[10], t4;
343
433
  }
344
434
  /** Where the icons an author reached for last are kept, in the browser rather than the dataset. */
345
435
  const storageKey = "driftime:sanity-plugin-icon:recent";
@@ -436,7 +526,7 @@ function getVisibleRows(scrollRow, count) {
436
526
  * @param index - Index of the icon to show.
437
527
  * @returns The position to scroll to.
438
528
  */
439
- function getCentredScrollTop(index) {
529
+ function getCenteredScrollTop(index) {
440
530
  return Math.max(0, Math.floor(index / 8) * 44 - 174);
441
531
  }
442
532
  /**
@@ -455,24 +545,22 @@ function getRevealedScrollTop(index, scrollTop) {
455
545
  function Picker(t0) {
456
546
  let $ = c(35), allowed, onSelect, props, selected;
457
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);
458
- 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), focusActiveCell = useRef(!1), scrollFrame = useRef(void 0), scrollStop = useRef(void 0), query = normaliseTerms(search), searching = isDefined(query), results = icons.filter((icon) => !searching || icon.terms.includes(query)), byName = new Map(icons.map(_temp)), recentIcons = searching ? [] : recent.flatMap((entry) => {
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) => {
459
549
  let icon_1 = byName.get(entry);
460
550
  return isDefined(icon_1) ? [icon_1] : [];
461
- }), { hovered, handleHover, clearHover } = useIconTooltip(byName, 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);
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);
462
552
  useEffect(() => {
463
553
  let element = scroller.current;
464
- isDefined(element) && selectedIndex !== -1 && (element.scrollTop = getCentredScrollTop(selectedIndex));
465
- }, [selectedIndex]);
554
+ isDefined(element) && selectedIndex !== -1 && (element.scrollTop = getCenteredScrollTop(selectedIndex));
555
+ }, [scroller, selectedIndex]);
466
556
  let t1, t2;
467
557
  $[5] === Symbol.for("react.memo_cache_sentinel") ? (t1 = () => () => {
468
558
  isDefined(scrollFrame.current) && cancelAnimationFrame(scrollFrame.current), isDefined(scrollStop.current) && clearTimeout(scrollStop.current);
469
559
  }, t2 = [], $[5] = t1, $[6] = t2) : (t1 = $[5], t2 = $[6]), useEffect(t1, t2);
470
- let t3;
471
- $[7] === Symbol.for("react.memo_cache_sentinel") ? (t3 = () => {
472
- focusActiveCell.current && (focusActiveCell.current = !1, isDefined(activeCell.current) && activeCell.current.focus());
473
- }, $[7] = t3) : t3 = $[7];
474
- let t4;
475
- $[8] === activeIndex ? t4 = $[9] : (t4 = [activeIndex], $[8] = activeIndex, $[9] = t4), useEffect(t3, t4);
560
+ let t3, t4;
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);
476
564
  let t5;
477
565
  $[10] !== onSelect || $[11] !== remember ? (t5 = function handleSelect(icon_3) {
478
566
  remember(icon_3.name), onSelect(icon_3);
@@ -511,11 +599,11 @@ function Picker(t0) {
511
599
  if (!isDefined(next)) return;
512
600
  event_1.preventDefault();
513
601
  let index = Math.min(Math.max(next, 0), last);
514
- focusActiveCell.current = !0, setMovedIndex(index);
602
+ focusIndex.current = index, setMovedIndex(index);
515
603
  let element_1 = scroller.current;
516
604
  isDefined(element_1) && (element_1.scrollTop = getRevealedScrollTop(index, element_1.scrollTop));
517
605
  }, t7;
518
- $[14] === Symbol.for("react.memo_cache_sentinel") ? (t7 = /* @__PURE__ */ jsx(SearchIcon, { ...defaultIconProps }), $[14] = t7) : t7 = $[14];
606
+ $[14] === Symbol.for("react.memo_cache_sentinel") ? (t7 = /* @__PURE__ */ jsx(SearchIcon, {}), $[14] = t7) : t7 = $[14];
519
607
  let t8;
520
608
  $[15] === library ? t8 = $[16] : (t8 = !isDefined(library) && /* @__PURE__ */ jsx(Flex, {
521
609
  align: "center",
@@ -535,7 +623,7 @@ function Picker(t0) {
535
623
  muted: !0,
536
624
  children: [
537
625
  "All icons (",
538
- results.length.toLocaleString("en-GB"),
626
+ results.length.toLocaleString("en-US"),
539
627
  ")"
540
628
  ]
541
629
  })
@@ -559,9 +647,9 @@ function Picker(t0) {
559
647
  activeCell,
560
648
  search,
561
649
  onSelect: handleSelect,
650
+ onHover: handleHover,
562
651
  onClearSearch: clearSearch,
563
652
  onScroll: handleScroll,
564
- onMouseOver: handleHover,
565
653
  onMouseLeave: clearHover,
566
654
  onKeyDown: handleGridKeyDown
567
655
  })
@@ -590,8 +678,8 @@ function Picker(t0) {
590
678
  icons: recentIcons,
591
679
  selected,
592
680
  onSelect: handleSelect,
681
+ onHover: handleHover,
593
682
  onForget: forget,
594
- onMouseOver: handleHover,
595
683
  onMouseLeave: clearHover
596
684
  }),
597
685
  t9,
@@ -603,60 +691,104 @@ function Picker(t0) {
603
691
  function _temp(icon_0) {
604
692
  return [icon_0.name, icon_0];
605
693
  }
694
+ function SquareDashedIcon(props) {
695
+ let $ = c(14), t0, t1, t10, t11, t2, t3, t4, t5, t6, t7, t8, t9;
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]);
697
+ let t12;
698
+ return $[12] === props ? t12 = $[13] : (t12 = /* @__PURE__ */ jsxs("svg", {
699
+ xmlns: "http://www.w3.org/2000/svg",
700
+ width: 24,
701
+ height: 24,
702
+ viewBox: "0 0 24 24",
703
+ fill: "none",
704
+ stroke: "currentColor",
705
+ strokeWidth: 2,
706
+ strokeLinecap: "round",
707
+ strokeLinejoin: "round",
708
+ ...props,
709
+ children: [
710
+ t0,
711
+ t1,
712
+ t2,
713
+ t3,
714
+ t4,
715
+ t5,
716
+ t6,
717
+ t7,
718
+ t8,
719
+ t9,
720
+ t10,
721
+ t11
722
+ ]
723
+ }), $[12] = props, $[13] = t12), t12;
724
+ }
725
+ /**
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.
728
+ *
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.
732
+ */
733
+ function resolveIconOptions(options, config) {
734
+ return { icons: options?.icons ?? config.icons };
735
+ }
606
736
  /** Type name of the icon object. */
607
737
  const iconTypeName = "icon";
608
738
  /**
609
- * Creates the input an icon field is drawn with, holding the icons the plugin was configured with so
610
- * a field naming its own replaces them rather than adding to them.
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.
611
741
  *
612
- * @param icons - Icons every field offers, or nothing to offer them all.
742
+ * @param config - Configuration every field falls back to.
613
743
  * @returns The input component.
614
744
  */
615
- function createInput(icons) {
745
+ function createInput(config) {
616
746
  function Input(t0) {
617
- let $ = c(29), { id, schemaType, value, onChange, readOnly } = t0, { name, node } = value ?? {}, [open, setOpen] = useState(!1), allowed = schemaType.options?.icons ?? icons, selectedNode = resolveIconNode(node), selectedLabel = isDefined(name) ? convertCase(name, "sentence") : void 0, t1;
618
- $[0] !== onChange || $[1] !== setOpen ? (t1 = function handleSelect(icon) {
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) {
619
751
  onChange([
620
752
  setIfMissing({ _type: iconTypeName }),
621
753
  set(icon.name, ["name"]),
622
- set(serialiseIconNode(icon.node), ["node"])
754
+ set(serializeIconNode(icon.node), ["node"])
623
755
  ]), setOpen(!1);
624
- }, $[0] = onChange, $[1] = setOpen, $[2] = t1) : t1 = $[2];
625
- let handleSelect = t1, T0 = Flex, T1 = Button, t5 = isDefined(selectedNode) ? /* @__PURE__ */ jsx(Drawing, {
756
+ }, $[2] = onChange, $[3] = setOpen, $[4] = t2) : t2 = $[4];
757
+ let handleSelect = t2, T0 = Flex, T1 = Button, t6 = isDefined(selectedNode) ? /* @__PURE__ */ jsx(Drawing, {
626
758
  node: selectedNode,
627
759
  ...defaultIconProps
628
- }) : void 0, t6 = selectedLabel ?? "Select icon", t7;
629
- $[3] === setOpen ? t7 = $[4] : (t7 = () => {
760
+ }) : /* @__PURE__ */ jsx(SquareDashedIcon, { ...defaultIconProps }), t7 = selectedLabel ?? "Select icon", t8;
761
+ $[5] === setOpen ? t8 = $[6] : (t8 = () => {
630
762
  setOpen(!0);
631
- }, $[3] = setOpen, $[4] = t7);
632
- let t8 = isDefined(selectedLabel) ? `${selectedLabel} currently selected` : "Select icon", t9;
633
- $[5] !== T1 || $[6] !== id || $[7] !== readOnly || $[8] !== t5 || $[9] !== t6 || $[10] !== t7 || $[11] !== t8 ? (t9 = /* @__PURE__ */ jsx(T1, {
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, {
634
766
  id,
635
767
  type: "button",
636
768
  mode: "ghost",
637
- icon: t5,
638
- text: t6,
769
+ icon: t6,
770
+ text: t7,
639
771
  disabled: readOnly,
640
- onClick: t7,
641
- "aria-label": t8
642
- }), $[5] = T1, $[6] = id, $[7] = readOnly, $[8] = t5, $[9] = t6, $[10] = t7, $[11] = t8, $[12] = t9) : t9 = $[12];
643
- let t10;
644
- $[13] !== onChange || $[14] !== readOnly || $[15] !== value ? (t10 = isDefined(value) && /* @__PURE__ */ jsx(Button, {
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, {
645
777
  type: "button",
646
778
  mode: "ghost",
647
779
  tone: "critical",
648
- icon: /* @__PURE__ */ jsx(CloseIcon, { ...defaultIconProps }),
780
+ icon: /* @__PURE__ */ jsx(CloseIcon, {}),
649
781
  text: "Clear",
650
782
  disabled: readOnly,
651
783
  onClick: () => {
652
784
  onChange(unset());
653
785
  },
654
- "aria-label": "Clear the currently selected icon."
655
- }), $[13] = onChange, $[14] = readOnly, $[15] = value, $[16] = t10) : t10 = $[16];
656
- let t11;
657
- $[17] !== allowed || $[18] !== handleSelect || $[19] !== id || $[20] !== name || $[21] !== open || $[22] !== setOpen ? (t11 = open && /* @__PURE__ */ jsx(Picker, {
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, {
658
790
  id: `${id}-library`,
659
- allowed,
791
+ allowed: icons,
660
792
  selected: name,
661
793
  onSelect: handleSelect,
662
794
  onClose: () => {
@@ -665,67 +797,19 @@ function createInput(icons) {
665
797
  onClickOutside: () => {
666
798
  setOpen(!1);
667
799
  }
668
- }), $[17] = allowed, $[18] = handleSelect, $[19] = id, $[20] = name, $[21] = open, $[22] = setOpen, $[23] = t11) : t11 = $[23];
669
- let t12;
670
- return $[24] !== T0 || $[25] !== t10 || $[26] !== t11 || $[27] !== t9 ? (t12 = /* @__PURE__ */ jsxs(T0, {
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, {
671
803
  gap: 2,
672
804
  children: [
673
- t9,
674
805
  t10,
675
- t11
806
+ t11,
807
+ t12
676
808
  ]
677
- }), $[24] = T0, $[25] = t10, $[26] = t11, $[27] = t9, $[28] = t12) : t12 = $[28], t12;
809
+ }), $[26] = T0, $[27] = t10, $[28] = t11, $[29] = t12, $[30] = t13) : t13 = $[30], t13;
678
810
  }
679
811
  return Input;
680
812
  }
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
813
  /**
730
814
  * Builds the media a stored icon previews with, so a document lists the drawing an author chose
731
815
  * rather than one placeholder standing in for every icon alike.
@@ -747,10 +831,10 @@ function createIconPreview(value) {
747
831
  * Creates the object type an icon is stored as, offering the icons it is given to every field that
748
832
  * does not name its own.
749
833
  *
750
- * @param icons - Icons every field offers, or nothing to offer them all.
834
+ * @param config - Configuration every field falls back to.
751
835
  * @returns An object type definition for a stored icon.
752
836
  */
753
- function createIconType(icons) {
837
+ function createIconType(config) {
754
838
  return defineType({
755
839
  name: iconTypeName,
756
840
  type: "object",
@@ -758,8 +842,9 @@ function createIconType(icons) {
758
842
  description: "Icon chosen from the Lucide library.",
759
843
  components: {
760
844
  field: Field,
761
- input: createInput(icons)
845
+ input: createInput(config)
762
846
  },
847
+ validation: (rule) => rule.custom((value) => !isDefined(value?.name) || isDefined(value.node) ? !0 : "Select the icon again so its drawing is stored."),
763
848
  preview: {
764
849
  select: {
765
850
  name: "name",
@@ -788,14 +873,10 @@ function createIconType(icons) {
788
873
  })]
789
874
  });
790
875
  }
791
- /** The plugin as Sanity defines it, wrapped below so that its configuration can genuinely be left out. */
792
- const plugin = definePlugin((config) => {
793
- let { icons } = config;
794
- return {
795
- name: "@driftime/sanity-plugin-icon",
796
- schema: { types: [createIconType(icons)] }
797
- };
798
- });
876
+ const plugin = definePlugin((config) => ({
877
+ name: "@driftime/sanity-plugin-icon",
878
+ schema: { types: [createIconType(config)] }
879
+ }));
799
880
  /**
800
881
  * Creates the icon field type for Sanity Studio, offering the Lucide library through a searchable
801
882
  * picker and storing the chosen drawing ready to render.