@mvriu5/payload-icon-picker 1.0.1 → 1.0.2

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 CHANGED
@@ -80,6 +80,14 @@ lucide:ArrowRight
80
80
 
81
81
  You can still use `resolveIcon` if you need a custom final storage format.
82
82
 
83
+ ### About `resolveIcon`
84
+
85
+ When using `payloadIconPlugin()`, `resolveIcon` runs during Payload config setup. The resolved string is passed to the admin field as each icon's final `value`.
86
+
87
+ That means normal `iconField()` usage does not require passing `resolveIcon` to the admin component manually.
88
+
89
+ The `resolveIcon` prop on `IconRenderer`, `IconField`, and `createIconResolver()` is primarily for direct component usage, tests, or advanced cases where you bypass `payloadIconPlugin()`. If you use a custom `resolveIcon` for stored values, pass the same resolver when rendering or resolving those values outside the Payload admin UI.
90
+
83
91
  ## Rendering Stored Icons
84
92
 
85
93
  Use `IconRenderer` from the client export to render a stored icon string in your frontend.
@@ -174,6 +182,8 @@ payloadIconPlugin({
174
182
 
175
183
  Adapters support `prefix`, `include`, `exclude`, and optional label/value formatters:
176
184
 
185
+ When registering icons from more than one library, use a unique `prefix` for every adapter. Many icon libraries export generic names such as `Home`, `Search`, or `User`; prefixes keep stored values unique and make it clear which library an icon came from.
186
+
177
187
  ```ts
178
188
  import * as SimpleIcons from "@icons-pack/react-simple-icons"
179
189
  import * as TablerIcons from "@tabler/icons-react"
@@ -195,6 +205,8 @@ payloadIconPlugin({
195
205
 
196
206
  With `prefix`, the adapter keeps `name` as the original library export name and sets `value` to `prefix:name`, for example `tabler:IconHome`.
197
207
 
208
+ Without prefixes, duplicate icon values can collide. In development, the plugin warns when multiple registered icons resolve to the same stored value.
209
+
198
210
  Or pass explicit icon metadata:
199
211
 
200
212
  ```ts
@@ -213,7 +225,7 @@ payloadIconPlugin({
213
225
 
214
226
  ## Field Options
215
227
 
216
- `iconField()` accepts normal single-value Payload text field options, plus picker labels:
228
+ `iconField()` accepts normal single-value Payload text field options, plus picker labels and per-field icon filters:
217
229
 
218
230
  ```ts
219
231
  iconField({
@@ -228,6 +240,36 @@ iconField({
228
240
  })
229
241
  ```
230
242
 
243
+ Use `libraries` to limit a field to icons from selected adapter prefixes:
244
+
245
+ ```ts
246
+ iconField({
247
+ name: "navigationIcon",
248
+ label: "Navigation Icon",
249
+ libraries: ["lucide"],
250
+ })
251
+ ```
252
+
253
+ Use `icons` to allow only specific stored icon values:
254
+
255
+ ```ts
256
+ iconField({
257
+ name: "socialIcon",
258
+ label: "Social Icon",
259
+ icons: ["si:SiGithub", "si:SiDiscord"],
260
+ })
261
+ ```
262
+
263
+ You can combine both options. The filters are additive, so this example allows all Lucide icons plus the explicit GitHub icon:
264
+
265
+ ```ts
266
+ iconField({
267
+ name: "featuredIcon",
268
+ libraries: ["lucide"],
269
+ icons: ["si:SiGithub"],
270
+ })
271
+ ```
272
+
231
273
  ## Development
232
274
 
233
275
  The dev Payload config in `dev/payload.config.ts` registers the plugin with `lucide-react`, which is installed as a development dependency.
@@ -1,7 +1,8 @@
1
1
  import type { IconFieldIcon } from "../utils.js";
2
2
  import type { IconAdapterOptions, IconLibrary } from "./utils.js";
3
- export type PhosphorIconWeight = "bold" | "duotone" | "fill" | "light" | "regular" | "thin";
3
+ type PhosphorIconWeight = "bold" | "duotone" | "fill" | "light" | "regular" | "thin";
4
4
  export type PhosphorIconAdapterOptions = Omit<IconAdapterOptions, "weight"> & {
5
5
  weight?: PhosphorIconWeight;
6
6
  };
7
7
  export declare const phosphorIconAdapter: (icons: IconLibrary, options?: PhosphorIconAdapterOptions) => IconFieldIcon[];
8
+ export {};
@@ -1,5 +1,4 @@
1
1
  import type { IconFieldIcon } from "../utils.js";
2
- export type IconNode = Array<[string, Record<string, unknown>]>;
3
2
  export type IconAdapterOptions = {
4
3
  exclude?: string[];
5
4
  include?: string[];
@@ -11,14 +10,15 @@ export type IconAdapterOptions = {
11
10
  weight?: string;
12
11
  };
13
12
  export type IconLibrary = Record<string, unknown>;
14
- export type IconAdapterLabelArgs = {
13
+ type IconAdapterLabelArgs = {
15
14
  defaultLabel: string;
16
15
  name: string;
17
16
  prefix?: string;
18
17
  value: string;
19
18
  };
20
- export type IconAdapterValueArgs = {
19
+ type IconAdapterValueArgs = {
21
20
  name: string;
22
21
  prefix?: string;
23
22
  };
24
23
  export declare const createSvgIconAdapter: (icons: IconLibrary, options?: IconAdapterOptions) => IconFieldIcon[];
24
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import React, { useEffect, useMemo, useState } from "react";
2
+ import React, { useEffect, useId, useMemo, useRef, useState } from "react";
3
3
  import { VirtuosoGrid } from "react-virtuoso";
4
4
  import "./IconDialog.css";
5
5
  import { sanitizeSvg } from "../sanitizeSvg.js";
@@ -8,6 +8,11 @@ import { getIconLabelParts, getIconLibrary } from "../utils.js";
8
8
  const SEARCH_DEBOUNCE_MS = 150;
9
9
  const ALL_LIBRARY_FILTER = "__all";
10
10
  export const IconDialog = ({ icons, isDisabled, noResultsLabel, onClear, onClose, onSelect, placeholder, resolveIcon, value })=>{
11
+ const dialogTitleId = useId();
12
+ const dialogDescriptionId = useId();
13
+ const dialogRef = useRef(null);
14
+ const searchInputRef = useRef(null);
15
+ const previouslyFocusedElementRef = useRef(null);
11
16
  const [query, setQuery] = useState("");
12
17
  const [activeLibrary, setActiveLibrary] = useState(ALL_LIBRARY_FILTER);
13
18
  const debouncedQuery = useDebouncedValue(query, SEARCH_DEBOUNCE_MS);
@@ -37,11 +42,42 @@ export const IconDialog = ({ icons, isDisabled, noResultsLabel, onClear, onClose
37
42
  icons,
38
43
  resolveIcon
39
44
  ]);
45
+ useEffect(()=>{
46
+ previouslyFocusedElementRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
47
+ searchInputRef.current?.focus();
48
+ return ()=>{
49
+ previouslyFocusedElementRef.current?.focus();
50
+ };
51
+ }, []);
40
52
  useEffect(()=>{
41
53
  const handleKeyDown = (event)=>{
42
54
  if (event.key === "Escape") {
43
55
  event.preventDefault();
44
56
  onClose();
57
+ return;
58
+ }
59
+ if (event.key !== "Tab") {
60
+ return;
61
+ }
62
+ const dialog = dialogRef.current;
63
+ if (!dialog) return;
64
+ const focusableElements = getFocusableElements(dialog);
65
+ if (focusableElements.length === 0) {
66
+ event.preventDefault();
67
+ dialog.focus();
68
+ return;
69
+ }
70
+ const firstFocusableElement = focusableElements[0];
71
+ const lastFocusableElement = focusableElements[focusableElements.length - 1];
72
+ if (!firstFocusableElement || !lastFocusableElement) return;
73
+ if (event.shiftKey && document.activeElement === firstFocusableElement) {
74
+ event.preventDefault();
75
+ lastFocusableElement.focus();
76
+ return;
77
+ }
78
+ if (!event.shiftKey && document.activeElement === lastFocusableElement) {
79
+ event.preventDefault();
80
+ firstFocusableElement.focus();
45
81
  }
46
82
  };
47
83
  window.addEventListener("keydown", handleKeyDown);
@@ -50,10 +86,14 @@ export const IconDialog = ({ icons, isDisabled, noResultsLabel, onClear, onClose
50
86
  onClose
51
87
  ]);
52
88
  return /*#__PURE__*/ _jsx("div", {
89
+ "aria-describedby": dialogDescriptionId,
90
+ "aria-labelledby": dialogTitleId,
53
91
  "aria-modal": "true",
54
92
  className: "payload-icon-picker__overlay",
55
93
  onClick: onClose,
94
+ ref: dialogRef,
56
95
  role: "dialog",
96
+ tabIndex: -1,
57
97
  children: /*#__PURE__*/ _jsxs("div", {
58
98
  className: "payload-icon-picker__dialog",
59
99
  onClick: (event)=>event.stopPropagation(),
@@ -63,21 +103,28 @@ export const IconDialog = ({ icons, isDisabled, noResultsLabel, onClear, onClose
63
103
  children: [
64
104
  /*#__PURE__*/ _jsx("h3", {
65
105
  className: "payload-icon-picker__dialog-title",
106
+ id: dialogTitleId,
66
107
  children: "Select icon"
67
108
  }),
68
109
  /*#__PURE__*/ _jsx("button", {
110
+ "aria-label": "Close icon picker",
69
111
  onClick: onClose,
70
112
  type: "button",
71
113
  children: "Close"
72
114
  })
73
115
  ]
74
116
  }),
117
+ /*#__PURE__*/ _jsx("p", {
118
+ id: dialogDescriptionId,
119
+ hidden: true,
120
+ children: "Search, filter, and select an icon. Press Escape to close the dialog."
121
+ }),
75
122
  /*#__PURE__*/ _jsx("input", {
76
- autoFocus: true,
77
123
  "aria-label": "Search icons",
78
124
  className: "payload-icon-picker__search",
79
125
  onChange: (event)=>setQuery(event.target.value),
80
126
  placeholder: placeholder,
127
+ ref: searchInputRef,
81
128
  type: "search",
82
129
  value: query
83
130
  }),
@@ -108,6 +155,7 @@ export const IconDialog = ({ icons, isDisabled, noResultsLabel, onClear, onClose
108
155
  const iconValue = resolveIcon(icon);
109
156
  const isSelected = iconValue === value;
110
157
  return /*#__PURE__*/ _jsxs("button", {
158
+ "aria-label": `Select ${icon.label ?? icon.name}`,
111
159
  "aria-selected": isSelected,
112
160
  className: "payload-icon-picker__option",
113
161
  onClick: ()=>{
@@ -164,6 +212,7 @@ const LibraryFilterButton = ({ isActive, label, onClick })=>/*#__PURE__*/ _jsx("
164
212
  type: "button",
165
213
  children: label
166
214
  });
215
+ const getFocusableElements = (element)=>Array.from(element.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter((focusableElement)=>!focusableElement.hasAttribute("hidden") && focusableElement.getAttribute("aria-hidden") !== "true");
167
216
  const useDebouncedValue = (value, delay)=>{
168
217
  const [debouncedValue, setDebouncedValue] = useState(value);
169
218
  useEffect(()=>{
@@ -7,6 +7,10 @@ export type IconFieldProps = TextFieldClientProps & {
7
7
  icons?: IconFieldIcon[] | IconFieldIconRecord;
8
8
  noResultsLabel?: string;
9
9
  placeholder?: string;
10
+ /**
11
+ * Primarily for direct component usage. With `payloadIconPlugin()`, icon
12
+ * values are already resolved before they reach this component.
13
+ */
10
14
  resolveIcon?: (icon: IconFieldIcon) => string;
11
15
  };
12
16
  export declare const IconField: React.FC<IconFieldProps>;
@@ -4,6 +4,10 @@ import type { IconFieldIcon, IconFieldIconRecord } from "../utils.js";
4
4
  export type IconRendererProps = Omit<HTMLAttributes<HTMLSpanElement>, "children" | "dangerouslySetInnerHTML"> & {
5
5
  fallback?: ReactNode;
6
6
  icons: IconFieldIcon[] | IconFieldIconRecord;
7
+ /**
8
+ * Maps registered icons to the stored string. Pass this when your stored
9
+ * values were produced with a custom `payloadIconPlugin({ resolveIcon })`.
10
+ */
7
11
  resolveIcon?: (icon: IconFieldIcon) => string;
8
12
  size?: number | string;
9
13
  value?: null | string;
package/dist/index.d.ts CHANGED
@@ -12,22 +12,42 @@ export type PayloadIconPluginConfig = {
12
12
  */
13
13
  disabled?: boolean;
14
14
  /**
15
- * Maps a selected icon to the string that is stored in Payload.
15
+ * Maps each registered icon to the final string stored in Payload.
16
+ *
17
+ * In normal `payloadIconPlugin()` + `iconField()` usage this runs during
18
+ * Payload config setup. The resolved string is then passed to the admin
19
+ * field as `icon.value`, so you do not need to also pass `resolveIcon` to
20
+ * the admin component manually.
16
21
  */
17
22
  resolveIcon?: (icon: IconFieldIcon) => string;
18
23
  };
19
24
  export type IconFieldConfig = Omit<TextField, "admin" | "hasMany" | "maxRows" | "minRows" | "type"> & {
20
25
  admin?: TextField["admin"];
26
+ /**
27
+ * Limit this field to icons whose final stored value uses one of these
28
+ * prefixes. Example: `["lucide"]` matches `lucide:Home`.
29
+ */
30
+ libraries?: string[];
21
31
  noResultsLabel?: string;
32
+ /**
33
+ * Limit this field to specific final stored icon values.
34
+ * Example: `["lucide:Home", "si:SiGithub"]`.
35
+ */
36
+ icons?: string[];
22
37
  placeholder?: string;
23
38
  };
24
39
  export type ResolveIconFromStringConfig = {
25
40
  icons: IconFieldIcon[] | IconFieldIconRecord;
41
+ /**
42
+ * Maps registered icons to the stored string. Use the same resolver that
43
+ * produced existing stored values when resolving icons outside the Payload
44
+ * admin UI.
45
+ */
26
46
  resolveIcon?: (icon: IconFieldIcon) => string;
27
47
  };
28
48
  export type ResolvedIcon = IconFieldIcon & {
29
49
  resolvedValue: string;
30
50
  };
31
- export declare const iconField: ({ admin, noResultsLabel, placeholder, ...field }: IconFieldConfig) => TextField;
51
+ export declare const iconField: ({ admin, icons, libraries, noResultsLabel, placeholder, ...field }: IconFieldConfig) => TextField;
32
52
  export declare const payloadIconPlugin: (pluginOptions: PayloadIconPluginConfig) => (config: Config) => Config;
33
53
  export declare const createIconResolver: ({ icons, resolveIcon }: ResolveIconFromStringConfig) => (value: null | string | undefined) => ResolvedIcon | undefined;
package/dist/index.js CHANGED
@@ -2,7 +2,8 @@ import { sanitizeSvg } from "./sanitizeSvg.js";
2
2
  import { normalizeIcons } from "./utils.js";
3
3
  const ICON_FIELD_MARKER = "payloadIconPicker";
4
4
  const ICON_FIELD_COMPONENT = "@mvriu5/payload-icon-picker/client#IconField";
5
- export const iconField = ({ admin, noResultsLabel, placeholder, ...field })=>({
5
+ const PACKAGE_NAME = "@mvriu5/payload-icon-picker";
6
+ export const iconField = ({ admin, icons, libraries, noResultsLabel, placeholder, ...field })=>({
6
7
  ...field,
7
8
  hasMany: false,
8
9
  type: "text",
@@ -11,6 +12,8 @@ export const iconField = ({ admin, noResultsLabel, placeholder, ...field })=>({
11
12
  custom: {
12
13
  ...admin?.custom ?? {},
13
14
  [ICON_FIELD_MARKER]: {
15
+ icons,
16
+ libraries,
14
17
  noResultsLabel,
15
18
  placeholder
16
19
  }
@@ -34,7 +37,9 @@ export const payloadIconPlugin = (pluginOptions)=>(config)=>{
34
37
  };
35
38
  export const createIconResolver = ({ icons, resolveIcon })=>{
36
39
  const iconMap = new Map();
37
- normalizeIcons(icons).forEach((icon)=>{
40
+ const normalizedIcons = normalizeIcons(icons);
41
+ warnAboutDuplicateIconValues(normalizedIcons, (icon)=>resolveIcon ? resolveIcon(icon) : icon.value ?? icon.name);
42
+ normalizedIcons.forEach((icon)=>{
38
43
  const resolvedValue = resolveIcon ? resolveIcon(icon) : icon.value ?? icon.name;
39
44
  iconMap.set(resolvedValue, {
40
45
  ...icon,
@@ -53,6 +58,8 @@ const withIconFields = (fields, icons)=>(fields ?? []).map((field)=>{
53
58
  const fieldWithNestedFields = field;
54
59
  if ("admin" in field && field.admin?.custom?.[ICON_FIELD_MARKER]) {
55
60
  const marker = field.admin.custom[ICON_FIELD_MARKER];
61
+ const fieldName = "name" in field && typeof field.name === "string" ? field.name : undefined;
62
+ const filteredIcons = filterIconsForField(icons, marker, fieldName);
56
63
  const textField = field;
57
64
  const admin = textField.admin;
58
65
  return {
@@ -63,7 +70,7 @@ const withIconFields = (fields, icons)=>(fields ?? []).map((field)=>{
63
70
  ...admin?.components ?? {},
64
71
  Field: {
65
72
  clientProps: {
66
- icons,
73
+ icons: filteredIcons,
67
74
  noResultsLabel: marker.noResultsLabel,
68
75
  placeholder: marker.placeholder
69
76
  },
@@ -101,7 +108,9 @@ const withIconFields = (fields, icons)=>(fields ?? []).map((field)=>{
101
108
  return field;
102
109
  });
103
110
  const normalizeIconsForClient = (icons, resolveIcon)=>{
104
- return normalizeIcons(icons).map(({ Icon, component, ...icon })=>{
111
+ const normalizedIcons = normalizeIcons(icons);
112
+ warnAboutDuplicateIconValues(normalizedIcons, (icon)=>resolveIcon ? resolveIcon(icon) : icon.value ?? icon.name);
113
+ return normalizedIcons.map(({ Icon, component, ...icon })=>{
105
114
  const sanitizedSvg = sanitizeSvg(icon.svg);
106
115
  return {
107
116
  ...icon,
@@ -114,3 +123,62 @@ const normalizeIconsForClient = (icons, resolveIcon)=>{
114
123
  };
115
124
  });
116
125
  };
126
+ const filterIconsForField = (icons, marker, fieldName)=>{
127
+ const allowedLibraries = new Set(marker.libraries ?? []);
128
+ const allowedIconValues = new Set(marker.icons ?? []);
129
+ if (allowedLibraries.size === 0 && allowedIconValues.size === 0) {
130
+ return icons;
131
+ }
132
+ const filteredIcons = icons.filter((icon)=>{
133
+ const library = getIconValueLibrary(icon.value);
134
+ return allowedIconValues.has(icon.value) || (library ? allowedLibraries.has(library) : false);
135
+ });
136
+ warnAboutUnmatchedIconFieldFilters({
137
+ allowedIconValues,
138
+ allowedLibraries,
139
+ fieldName,
140
+ filteredIcons,
141
+ icons
142
+ });
143
+ return filteredIcons;
144
+ };
145
+ const getIconValueLibrary = (value)=>{
146
+ const separatorIndex = value.indexOf(":");
147
+ if (separatorIndex <= 0) {
148
+ return undefined;
149
+ }
150
+ return value.slice(0, separatorIndex);
151
+ };
152
+ const warnAboutUnmatchedIconFieldFilters = ({ allowedIconValues, allowedLibraries, fieldName, filteredIcons, icons })=>{
153
+ if (isProduction()) return;
154
+ const knownIconValues = new Set(icons.map((icon)=>icon.value));
155
+ const knownLibraries = new Set(icons.map((icon)=>getIconValueLibrary(icon.value)).filter((library)=>Boolean(library)));
156
+ const unknownIconValues = Array.from(allowedIconValues).filter((value)=>!knownIconValues.has(value));
157
+ const unknownLibraries = Array.from(allowedLibraries).filter((library)=>!knownLibraries.has(library));
158
+ const fieldLabel = fieldName ? `iconField("${fieldName}")` : "iconField()";
159
+ if (unknownIconValues.length > 0) {
160
+ console.warn(`[${PACKAGE_NAME}] ${fieldLabel} references unknown icon values: ${unknownIconValues.map((value)=>`"${value}"`).join(", ")}. ` + "Make sure the matching icons are registered in payloadIconPlugin().");
161
+ }
162
+ if (unknownLibraries.length > 0) {
163
+ console.warn(`[${PACKAGE_NAME}] ${fieldLabel} references unknown icon libraries: ${unknownLibraries.map((library)=>`"${library}"`).join(", ")}. ` + "Make sure the matching adapters use these prefixes in payloadIconPlugin().");
164
+ }
165
+ if (filteredIcons.length === 0) {
166
+ console.warn(`[${PACKAGE_NAME}] ${fieldLabel} filter matched no icons. The picker will render with an empty icon list.`);
167
+ }
168
+ };
169
+ const warnAboutDuplicateIconValues = (icons, resolveValue)=>{
170
+ if (isProduction()) return;
171
+ const iconsByValue = new Map();
172
+ icons.forEach((icon)=>{
173
+ const value = resolveValue(icon);
174
+ const names = iconsByValue.get(value) ?? [];
175
+ names.push(icon.name);
176
+ iconsByValue.set(value, names);
177
+ });
178
+ const duplicateMessages = Array.from(iconsByValue.entries()).filter(([, names])=>names.length > 1).map(([value, names])=>`"${value}" used by ${names.map((name)=>`"${name}"`).join(", ")}`);
179
+ if (duplicateMessages.length === 0) {
180
+ return;
181
+ }
182
+ console.warn(`[${PACKAGE_NAME}] Duplicate icon values detected: ${duplicateMessages.join("; ")}. ` + "Icon values must be unique so stored values resolve predictably. Use adapter prefixes to avoid collisions.");
183
+ };
184
+ const isProduction = ()=>typeof process !== "undefined" && process.env.NODE_ENV === "production";
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { ElementType } from "react";
2
- export type IconComponent = ElementType<{
2
+ type IconComponent = ElementType<{
3
3
  "aria-hidden"?: boolean;
4
4
  className?: string;
5
5
  focusable?: boolean;
@@ -17,13 +17,9 @@ export type IconFieldIcon = {
17
17
  export type IconFieldIconRecord = Record<string, IconComponent> | Record<string, IconFieldIcon>;
18
18
  export declare const defaultResolveIcon: (icon: IconFieldIcon) => string;
19
19
  export declare const normalizeIcons: (icons: IconFieldIcon[] | IconFieldIconRecord | undefined) => IconFieldIcon[];
20
- export declare const isIconComponent: (icon: IconComponent | IconFieldIcon) => icon is IconComponent;
21
20
  export declare const getIconLabelParts: (icon: IconFieldIcon, resolveIcon: (icon: IconFieldIcon) => string) => {
22
21
  name: string;
23
22
  prefix?: string;
24
23
  };
25
24
  export declare const getIconLibrary: (icon: IconFieldIcon, resolveIcon: (icon: IconFieldIcon) => string) => string | undefined;
26
- export declare const splitPrefixedValue: (value: string) => {
27
- name: string;
28
- prefix: string;
29
- } | undefined;
25
+ export {};
package/dist/utils.js CHANGED
@@ -19,7 +19,7 @@ export const normalizeIcons = (icons)=>{
19
19
  };
20
20
  });
21
21
  };
22
- export const isIconComponent = (icon)=>{
22
+ const isIconComponent = (icon)=>{
23
23
  if (typeof icon === "function" || typeof icon === "string") {
24
24
  return true;
25
25
  }
@@ -41,7 +41,7 @@ export const getIconLabelParts = (icon, resolveIcon)=>{
41
41
  };
42
42
  };
43
43
  export const getIconLibrary = (icon, resolveIcon)=>splitPrefixedValue(resolveIcon(icon))?.prefix;
44
- export const splitPrefixedValue = (value)=>{
44
+ const splitPrefixedValue = (value)=>{
45
45
  const separatorIndex = value.indexOf(":");
46
46
  if (separatorIndex <= 0 || separatorIndex === value.length - 1) return undefined;
47
47
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mvriu5/payload-icon-picker",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Payload plugin introducing an icon picker into the CMS.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -88,7 +88,6 @@
88
88
  "@types/react-dom": "19.2.3",
89
89
  "copyfiles": "2.4.1",
90
90
  "cross-env": "^7.0.3",
91
- "eslint": "^9.23.0",
92
91
  "graphql": "^17.0.2",
93
92
  "knip": "^6.24.0",
94
93
  "lucide-react": "^1.23.0",
@@ -162,7 +161,6 @@
162
161
  "entry": [
163
162
  "src/exports/client.ts",
164
163
  "dev/payload.config.ts",
165
- "dev/next.config.mjs",
166
164
  "dev/app/**/*.{ts,tsx}"
167
165
  ],
168
166
  "ignore": [