@pro-laico/payload-icons 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +22 -0
- package/README.md +9 -0
- package/dist/cache/index.d.ts +9 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +96 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/collections/Icon.d.ts +14 -0
- package/dist/collections/Icon.d.ts.map +1 -0
- package/dist/collections/Icon.js +96 -0
- package/dist/collections/Icon.js.map +1 -0
- package/dist/collections/IconRequest.d.ts +30 -0
- package/dist/collections/IconRequest.d.ts.map +1 -0
- package/dist/collections/IconRequest.js +82 -0
- package/dist/collections/IconRequest.js.map +1 -0
- package/dist/collections/IconSet.d.ts +43 -0
- package/dist/collections/IconSet.d.ts.map +1 -0
- package/dist/collections/IconSet.js +168 -0
- package/dist/collections/IconSet.js.map +1 -0
- package/dist/components/Icon.d.ts +35 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +56 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/admin/clearIconRequests.d.ts +14 -0
- package/dist/components/admin/clearIconRequests.d.ts.map +1 -0
- package/dist/components/admin/clearIconRequests.js +52 -0
- package/dist/components/admin/clearIconRequests.js.map +1 -0
- package/dist/components/admin/iconPreview.d.ts +7 -0
- package/dist/components/admin/iconPreview.d.ts.map +1 -0
- package/dist/components/admin/iconPreview.js +49 -0
- package/dist/components/admin/iconPreview.js.map +1 -0
- package/dist/components/admin/iconRowLabel.d.ts +8 -0
- package/dist/components/admin/iconRowLabel.d.ts.map +1 -0
- package/dist/components/admin/iconRowLabel.js +28 -0
- package/dist/components/admin/iconRowLabel.js.map +1 -0
- package/dist/components/admin/iconUsagePanel.client.d.ts +26 -0
- package/dist/components/admin/iconUsagePanel.client.d.ts.map +1 -0
- package/dist/components/admin/iconUsagePanel.client.js +290 -0
- package/dist/components/admin/iconUsagePanel.client.js.map +1 -0
- package/dist/components/admin/iconUsagePanel.d.ts +12 -0
- package/dist/components/admin/iconUsagePanel.d.ts.map +1 -0
- package/dist/components/admin/iconUsagePanel.js +68 -0
- package/dist/components/admin/iconUsagePanel.js.map +1 -0
- package/dist/hooks/formatSVG.d.ts +22 -0
- package/dist/hooks/formatSVG.d.ts.map +1 -0
- package/dist/hooks/formatSVG.js +270 -0
- package/dist/hooks/formatSVG.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/activeField.d.ts +24 -0
- package/dist/lib/activeField.d.ts.map +1 -0
- package/dist/lib/activeField.js +71 -0
- package/dist/lib/activeField.js.map +1 -0
- package/dist/lib/authenticated.d.ts +5 -0
- package/dist/lib/authenticated.d.ts.map +1 -0
- package/dist/lib/authenticated.js +4 -0
- package/dist/lib/authenticated.js.map +1 -0
- package/dist/lib/defaultAccess.d.ts +8 -0
- package/dist/lib/defaultAccess.d.ts.map +1 -0
- package/dist/lib/defaultAccess.js +6 -0
- package/dist/lib/defaultAccess.js.map +1 -0
- package/dist/lib/extractSVG.d.ts +3 -0
- package/dist/lib/extractSVG.d.ts.map +1 -0
- package/dist/lib/extractSVG.js +27 -0
- package/dist/lib/extractSVG.js.map +1 -0
- package/dist/lib/getPayloadClient.d.ts +22 -0
- package/dist/lib/getPayloadClient.d.ts.map +1 -0
- package/dist/lib/getPayloadClient.js +39 -0
- package/dist/lib/getPayloadClient.js.map +1 -0
- package/dist/lib/mergeHooks.d.ts +8 -0
- package/dist/lib/mergeHooks.d.ts.map +1 -0
- package/dist/lib/mergeHooks.js +19 -0
- package/dist/lib/mergeHooks.js.map +1 -0
- package/dist/lib/titleCase.d.ts +7 -0
- package/dist/lib/titleCase.d.ts.map +1 -0
- package/dist/lib/titleCase.js +17 -0
- package/dist/lib/titleCase.js.map +1 -0
- package/dist/plugin.d.ts +91 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +72 -0
- package/dist/plugin.js.map +1 -0
- package/dist/scan/cli.d.ts +14 -0
- package/dist/scan/cli.d.ts.map +1 -0
- package/dist/scan/cli.js +114 -0
- package/dist/scan/cli.js.map +1 -0
- package/dist/scan/extract.d.ts +58 -0
- package/dist/scan/extract.d.ts.map +1 -0
- package/dist/scan/extract.js +286 -0
- package/dist/scan/extract.js.map +1 -0
- package/dist/scan/index.d.ts +81 -0
- package/dist/scan/index.d.ts.map +1 -0
- package/dist/scan/index.js +133 -0
- package/dist/scan/index.js.map +1 -0
- package/dist/scan/live.d.ts +20 -0
- package/dist/scan/live.d.ts.map +1 -0
- package/dist/scan/live.js +109 -0
- package/dist/scan/live.js.map +1 -0
- package/dist/scan/load.d.ts +28 -0
- package/dist/scan/load.d.ts.map +1 -0
- package/dist/scan/load.js +37 -0
- package/dist/scan/load.js.map +1 -0
- package/dist/scan/types.d.ts +29 -0
- package/dist/scan/types.d.ts.map +1 -0
- package/dist/scan/types.js +8 -0
- package/dist/scan/types.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/usage/recordMiss.d.ts +17 -0
- package/dist/usage/recordMiss.d.ts.map +1 -0
- package/dist/usage/recordMiss.js +60 -0
- package/dist/usage/recordMiss.js.map +1 -0
- package/dist/usage/trackIconMiss.d.ts +16 -0
- package/dist/usage/trackIconMiss.d.ts.map +1 -0
- package/dist/usage/trackIconMiss.js +43 -0
- package/dist/usage/trackIconMiss.js.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/collections/IconSet.ts"],"sourcesContent":["import type { CollectionConfig, CollectionSlug, Field, PayloadRequest } from 'payload'\n\nimport { activeField, enforceSingleActive } from '../lib/activeField'\nimport { authd } from '../lib/authenticated'\nimport { mergeHooks } from '../lib/mergeHooks'\nimport { toKebabCase } from '../lib/titleCase'\n\n/** The default slug for the icon-set collection. */\nexport const ICON_SET_SLUG = 'iconSet'\n\n/** Admin import-map path for the IconSet \"requested icons\" usage panel. */\nconst IconUsagePanelPath = '@pro-laico/payload-icons/admin/iconUsagePanel'\n\n/** Admin import-map path for the per-row label inside `iconsArray`. */\nconst IconRowLabelPath = '@pro-laico/payload-icons/admin/iconRowLabel'\n\n/** Inline title field so the collection has no template dependency. */\nconst titleField = (defaultValue = 'New Icon Set'): Field => ({ name: 'title', type: 'text', required: true, unique: true, defaultValue })\n\n/**\n * Overrides for the `iconSet` collection — a named, ordered `name → icon` mapping\n * into the shared `icon` pool. One set is `active` at a time; the frontend renders\n * it (see {@link enforceSingleActive}).\n */\nexport interface IconSetCollectionOverrides {\n /** Slug for the icon-set collection. @default 'iconSet' */\n slug?: string\n /**\n * Live-preview URL generator. When provided, wires both `admin.preview`\n * (legacy iframe) and `admin.livePreview.url`. Omitted by default.\n */\n livePreviewUrl?: (args: { data: Record<string, unknown>; req: PayloadRequest }) => string | Promise<string>\n /** Override the `admin.group` sidebar label. @default 'Sets' */\n group?: string\n /** Additional collection hooks. */\n hooks?: CollectionConfig['hooks']\n /** Extra set-level fields appended to the Settings tab, below the title. */\n fields?: Field[]\n /** Extra fields appended to each `iconsArray` row, after the built-in `name` + `icon`. */\n iconRowFields?: Field[]\n /** Enable drafts/versions on the collection (per-set draft → publish). @default true */\n drafts?: boolean\n}\n\n/**\n * Builds the `iconSet` collection — a named `name → icon` mapping with a\n * single-active toggle; the frontend renders the active set.\n *\n * `iconSlug` and `usagePanel` are wired by the plugin (from the icon collection's\n * slug and the top-level `usagePanel` option); they aren't part of the public\n * override surface.\n */\nexport const createIconSetCollection = (\n opts: IconSetCollectionOverrides & { iconSlug?: string; usagePanel?: boolean } = {},\n): CollectionConfig => {\n const {\n slug = ICON_SET_SLUG,\n iconSlug = 'icon',\n livePreviewUrl,\n group = 'Sets',\n hooks,\n fields: extraFields = [],\n iconRowFields = [],\n usagePanel = true,\n drafts = true,\n } = opts\n\n // The \"Requested icons\" panel — a server UI field that scans usage (live in dev,\n // manifest in prod) and diffs it against this set's icons. Config-free: the panel\n // uses its defaults (ICON_USAGE_MANIFEST env for the manifest path in prod).\n const usageField: Field[] = usagePanel ? [{ name: 'iconUsage', type: 'ui', admin: { components: { Field: IconUsagePanelPath } } }] : []\n\n return {\n slug,\n labels: { singular: 'Icon Set', plural: 'Icon Sets' },\n access: { create: authd, delete: authd, read: authd, update: authd },\n admin: {\n group,\n useAsTitle: 'title',\n defaultColumns: ['title', 'active', '_status'],\n ...(livePreviewUrl && {\n preview: (data, { req }) => livePreviewUrl({ data: data as Record<string, unknown>, req }),\n livePreview: { url: ({ data, req }) => livePreviewUrl({ data: data as Record<string, unknown>, req }) },\n }),\n },\n fields: [\n {\n type: 'tabs',\n tabs: [\n { label: 'Settings', fields: [{ type: 'row', fields: [activeField, titleField('New Icon Set')] }, ...extraFields, ...usageField] },\n {\n label: 'Icons',\n fields: [\n {\n name: 'iconsArray',\n type: 'array',\n label: 'Icons',\n labels: { singular: 'Icon', plural: 'Icons' },\n admin: { initCollapsed: true, components: { RowLabel: IconRowLabelPath } },\n fields: [\n {\n type: 'row',\n fields: [\n {\n name: 'name',\n type: 'text',\n required: true,\n // Normalize to kebab-case so the typed name matches `<Icon name>`.\n hooks: { beforeValidate: [({ value }) => (typeof value === 'string' ? toKebabCase(value) : value)] },\n admin: {\n width: '25%',\n description: 'The name the frontend looks the icon up by (auto kebab-cased).',\n style: { maxWidth: '350px' },\n },\n },\n {\n name: 'icon',\n type: 'upload',\n relationTo: iconSlug as CollectionSlug,\n displayPreview: false,\n admin: { allowCreate: false, width: '75%', description: 'Select an icon.', style: { maxWidth: '350px' } },\n },\n ...iconRowFields,\n ],\n },\n ],\n },\n ],\n },\n ],\n },\n ],\n hooks: mergeHooks({ beforeChange: [enforceSingleActive] }, hooks),\n ...(drafts ? { versions: { drafts: { schedulePublish: true }, maxPerDoc: 50 } } : {}),\n }\n}\n"],"names":["activeField","enforceSingleActive","authd","mergeHooks","toKebabCase","ICON_SET_SLUG","IconUsagePanelPath","IconRowLabelPath","titleField","defaultValue","name","type","required","unique","createIconSetCollection","opts","slug","iconSlug","livePreviewUrl","group","hooks","fields","extraFields","iconRowFields","usagePanel","drafts","usageField","admin","components","Field","labels","singular","plural","access","create","delete","read","update","useAsTitle","defaultColumns","preview","data","req","livePreview","url","tabs","label","initCollapsed","RowLabel","beforeValidate","value","width","description","style","maxWidth","relationTo","displayPreview","allowCreate","beforeChange","versions","schedulePublish","maxPerDoc"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
export interface IconProps extends React.SVGAttributes<SVGSVGElement> {
|
|
4
|
+
/**
|
|
5
|
+
* Icon name as defined in the active `iconSet`'s `iconsArray` (each entry's
|
|
6
|
+
* `name` field). Resolved server-side through the active set, so swapping the
|
|
7
|
+
* active set re-skins every icon.
|
|
8
|
+
*/
|
|
9
|
+
name: string;
|
|
10
|
+
/**
|
|
11
|
+
* Optional fallback SVG string used when `name` doesn't match any icon in the
|
|
12
|
+
* active set. Defaults to a small inline warning glyph.
|
|
13
|
+
*/
|
|
14
|
+
fallback?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Renders a CMS-managed icon by name. Server component — looks up the active
|
|
18
|
+
* `iconSet`, finds the entry matching `name`, and inlines its `<svg>` with the
|
|
19
|
+
* source's intrinsic attributes (viewBox, fill, …) merged under any JSX props
|
|
20
|
+
* you pass (so `className`, `style`, `width`, etc. always win). It inherits CSS
|
|
21
|
+
* `color` via `currentColor`. Falls back to {@link IconProps.fallback} (or a
|
|
22
|
+
* built-in warning glyph) when the name doesn't resolve.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* import { Icon } from '@pro-laico/payload-icons/components/Icon'
|
|
27
|
+
*
|
|
28
|
+
* <Icon name="arrow-right" />
|
|
29
|
+
* <Icon name="arrow-right" className="size-6 text-primary" />
|
|
30
|
+
* <Icon name="logo" fallback={myCustomSvgString} />
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const Icon: ({ name, fallback, ...svgProps }: IconProps) => Promise<React.ReactElement>;
|
|
34
|
+
export default Icon;
|
|
35
|
+
//# sourceMappingURL=Icon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/components/Icon.tsx"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAA;AAEpB,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAc9B,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,aAAa,CAAC,aAAa,CAAC;IACnE;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,IAAI,GAAU,iCAAiC,SAAS,KAAG,OAAO,CAAC,KAAK,CAAC,YAAY,CAwBjG,CAAA;AAED,eAAe,IAAI,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "server-only";
|
|
3
|
+
import { draftMode } from "next/headers";
|
|
4
|
+
import { getIconSvg, warnIconMissDev } from "../cache/index.js";
|
|
5
|
+
import { extractSvgContent, extractSvgProps } from "../lib/extractSVG.js";
|
|
6
|
+
import { trackIconMiss } from "../usage/trackIconMiss.js";
|
|
7
|
+
/**
|
|
8
|
+
* Inline fallback rendered when `name` doesn't resolve. Kept local so the
|
|
9
|
+
* component carries no extra dependency — pass {@link IconProps.fallback} to
|
|
10
|
+
* override it with your own SVG string.
|
|
11
|
+
*/ const FALLBACK_WARNING_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="10.7 10.7 106.6 106.6" fill="currentColor" stroke="currentColor"><path d="M64 37.3a5.3 5.3 0 015.3 5.4v26.6a5.3 5.3 0 11-10.6 0V42.7a5.3 5.3 0 015.3-5.4m0 53.4A5.3 5.3 0 0064 80a5.3 5.3 0 000 10.7"/><path fill-rule="evenodd" d="M10.7 64a53.3 53.3 0 11106.6 0 53.3 53.3 0 01-106.6 0M64 21.3a42.7 42.7 0 100 85.4 42.7 42.7 0 000-85.4"/></svg>`;
|
|
12
|
+
/**
|
|
13
|
+
* Renders a CMS-managed icon by name. Server component — looks up the active
|
|
14
|
+
* `iconSet`, finds the entry matching `name`, and inlines its `<svg>` with the
|
|
15
|
+
* source's intrinsic attributes (viewBox, fill, …) merged under any JSX props
|
|
16
|
+
* you pass (so `className`, `style`, `width`, etc. always win). It inherits CSS
|
|
17
|
+
* `color` via `currentColor`. Falls back to {@link IconProps.fallback} (or a
|
|
18
|
+
* built-in warning glyph) when the name doesn't resolve.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import { Icon } from '@pro-laico/payload-icons/components/Icon'
|
|
23
|
+
*
|
|
24
|
+
* <Icon name="arrow-right" />
|
|
25
|
+
* <Icon name="arrow-right" className="size-6 text-primary" />
|
|
26
|
+
* <Icon name="logo" fallback={myCustomSvgString} />
|
|
27
|
+
* ```
|
|
28
|
+
*/ export const Icon = async ({ name, fallback, ...svgProps })=>{
|
|
29
|
+
const { isEnabled: draft } = await draftMode();
|
|
30
|
+
const svg = await getIconSvg(name, draft);
|
|
31
|
+
// Name didn't resolve against the active set — record it (throttled,
|
|
32
|
+
// fire-and-forget) so the admin "Requested icons" panel can surface real
|
|
33
|
+
// runtime misses, including dynamic names a static scan can't see.
|
|
34
|
+
if (!svg) {
|
|
35
|
+
trackIconMiss(name);
|
|
36
|
+
void warnIconMissDev(name, draft); // dev-only, once per name — diagnoses WHY the name missed
|
|
37
|
+
}
|
|
38
|
+
const source = svg || fallback || FALLBACK_WARNING_SVG;
|
|
39
|
+
// Default to decorative (aria-hidden); callers announcing the icon override
|
|
40
|
+
// with `aria-hidden={false}` + a title since svgProps wins over this default.
|
|
41
|
+
// `data-icon-missing` marks fallback renders so multiple misses on a page are distinguishable.
|
|
42
|
+
return /*#__PURE__*/ _jsx("svg", {
|
|
43
|
+
"aria-hidden": "true",
|
|
44
|
+
...svg ? {} : {
|
|
45
|
+
'data-icon-missing': name
|
|
46
|
+
},
|
|
47
|
+
...extractSvgProps(source),
|
|
48
|
+
...svgProps,
|
|
49
|
+
dangerouslySetInnerHTML: {
|
|
50
|
+
__html: extractSvgContent(source)
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
export default Icon;
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=Icon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/Icon.tsx"],"sourcesContent":["import 'server-only'\n\nimport type React from 'react'\nimport { draftMode } from 'next/headers'\n\nimport { getIconSvg, warnIconMissDev } from '../cache'\nimport { extractSvgContent, extractSvgProps } from '../lib/extractSVG'\nimport { trackIconMiss } from '../usage/trackIconMiss'\n\n/**\n * Inline fallback rendered when `name` doesn't resolve. Kept local so the\n * component carries no extra dependency — pass {@link IconProps.fallback} to\n * override it with your own SVG string.\n */\nconst FALLBACK_WARNING_SVG = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"10.7 10.7 106.6 106.6\" fill=\"currentColor\" stroke=\"currentColor\"><path d=\"M64 37.3a5.3 5.3 0 015.3 5.4v26.6a5.3 5.3 0 11-10.6 0V42.7a5.3 5.3 0 015.3-5.4m0 53.4A5.3 5.3 0 0064 80a5.3 5.3 0 000 10.7\"/><path fill-rule=\"evenodd\" d=\"M10.7 64a53.3 53.3 0 11106.6 0 53.3 53.3 0 01-106.6 0M64 21.3a42.7 42.7 0 100 85.4 42.7 42.7 0 000-85.4\"/></svg>`\n\nexport interface IconProps extends React.SVGAttributes<SVGSVGElement> {\n /**\n * Icon name as defined in the active `iconSet`'s `iconsArray` (each entry's\n * `name` field). Resolved server-side through the active set, so swapping the\n * active set re-skins every icon.\n */\n name: string\n /**\n * Optional fallback SVG string used when `name` doesn't match any icon in the\n * active set. Defaults to a small inline warning glyph.\n */\n fallback?: string\n}\n\n/**\n * Renders a CMS-managed icon by name. Server component — looks up the active\n * `iconSet`, finds the entry matching `name`, and inlines its `<svg>` with the\n * source's intrinsic attributes (viewBox, fill, …) merged under any JSX props\n * you pass (so `className`, `style`, `width`, etc. always win). It inherits CSS\n * `color` via `currentColor`. Falls back to {@link IconProps.fallback} (or a\n * built-in warning glyph) when the name doesn't resolve.\n *\n * @example\n * ```tsx\n * import { Icon } from '@pro-laico/payload-icons/components/Icon'\n *\n * <Icon name=\"arrow-right\" />\n * <Icon name=\"arrow-right\" className=\"size-6 text-primary\" />\n * <Icon name=\"logo\" fallback={myCustomSvgString} />\n * ```\n */\nexport const Icon = async ({ name, fallback, ...svgProps }: IconProps): Promise<React.ReactElement> => {\n const { isEnabled: draft } = await draftMode()\n const svg = await getIconSvg(name, draft)\n // Name didn't resolve against the active set — record it (throttled,\n // fire-and-forget) so the admin \"Requested icons\" panel can surface real\n // runtime misses, including dynamic names a static scan can't see.\n if (!svg) {\n trackIconMiss(name)\n void warnIconMissDev(name, draft) // dev-only, once per name — diagnoses WHY the name missed\n }\n const source = svg || fallback || FALLBACK_WARNING_SVG\n\n // Default to decorative (aria-hidden); callers announcing the icon override\n // with `aria-hidden={false}` + a title since svgProps wins over this default.\n // `data-icon-missing` marks fallback renders so multiple misses on a page are distinguishable.\n return (\n <svg\n aria-hidden=\"true\"\n {...(svg ? {} : { 'data-icon-missing': name })}\n {...extractSvgProps(source)}\n {...svgProps}\n dangerouslySetInnerHTML={{ __html: extractSvgContent(source) }}\n />\n )\n}\n\nexport default Icon\n"],"names":["draftMode","getIconSvg","warnIconMissDev","extractSvgContent","extractSvgProps","trackIconMiss","FALLBACK_WARNING_SVG","Icon","name","fallback","svgProps","isEnabled","draft","svg","source","aria-hidden","dangerouslySetInnerHTML","__html"],"mappings":";AAAA,OAAO,cAAa;AAGpB,SAASA,SAAS,QAAQ,eAAc;AAExC,SAASC,UAAU,EAAEC,eAAe,QAAQ,oBAAU;AACtD,SAASC,iBAAiB,EAAEC,eAAe,QAAQ,uBAAmB;AACtE,SAASC,aAAa,QAAQ,4BAAwB;AAEtD;;;;CAIC,GACD,MAAMC,uBAAuB,CAAC,qYAAqY,CAAC;AAgBpa;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,MAAMC,OAAO,OAAO,EAAEC,IAAI,EAAEC,QAAQ,EAAE,GAAGC,UAAqB;IACnE,MAAM,EAAEC,WAAWC,KAAK,EAAE,GAAG,MAAMZ;IACnC,MAAMa,MAAM,MAAMZ,WAAWO,MAAMI;IACnC,qEAAqE;IACrE,yEAAyE;IACzE,mEAAmE;IACnE,IAAI,CAACC,KAAK;QACRR,cAAcG;QACd,KAAKN,gBAAgBM,MAAMI,QAAO,0DAA0D;IAC9F;IACA,MAAME,SAASD,OAAOJ,YAAYH;IAElC,4EAA4E;IAC5E,8EAA8E;IAC9E,+FAA+F;IAC/F,qBACE,KAACO;QACCE,eAAY;QACX,GAAIF,MAAM,CAAC,IAAI;YAAE,qBAAqBL;QAAK,CAAC;QAC5C,GAAGJ,gBAAgBU,OAAO;QAC1B,GAAGJ,QAAQ;QACZM,yBAAyB;YAAEC,QAAQd,kBAAkBW;QAAQ;;AAGnE,EAAC;AAED,eAAeP,KAAI"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server action behind the IconSet usage panel's "Clear runtime requests"
|
|
3
|
+
* button: deletes every row in the `iconRequest` collection so the panel's live
|
|
4
|
+
* miss list starts fresh (e.g. after you've added the missing icons).
|
|
5
|
+
*
|
|
6
|
+
* Auth-gated to the logged-in admin via the request headers, and the delete
|
|
7
|
+
* runs with `overrideAccess: false` so the collection's own access still
|
|
8
|
+
* applies. A no-op (reported as such) when tracking isn't enabled.
|
|
9
|
+
*/
|
|
10
|
+
export declare function clearIconRequests(): Promise<{
|
|
11
|
+
success: boolean;
|
|
12
|
+
message: string;
|
|
13
|
+
}>;
|
|
14
|
+
//# sourceMappingURL=clearIconRequests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clearIconRequests.d.ts","sourceRoot":"","sources":["../../../src/components/admin/clearIconRequests.ts"],"names":[],"mappings":"AAQA;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBxF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { headers as nextHeaders } from "next/headers";
|
|
3
|
+
import { ICON_REQUEST_SLUG } from "../../collections/IconRequest.js";
|
|
4
|
+
import { getPayloadClient } from "../../lib/getPayloadClient.js";
|
|
5
|
+
/**
|
|
6
|
+
* Server action behind the IconSet usage panel's "Clear runtime requests"
|
|
7
|
+
* button: deletes every row in the `iconRequest` collection so the panel's live
|
|
8
|
+
* miss list starts fresh (e.g. after you've added the missing icons).
|
|
9
|
+
*
|
|
10
|
+
* Auth-gated to the logged-in admin via the request headers, and the delete
|
|
11
|
+
* runs with `overrideAccess: false` so the collection's own access still
|
|
12
|
+
* applies. A no-op (reported as such) when tracking isn't enabled.
|
|
13
|
+
*/ export async function clearIconRequests() {
|
|
14
|
+
try {
|
|
15
|
+
const payload = await getPayloadClient();
|
|
16
|
+
const { user } = await payload.auth({
|
|
17
|
+
headers: await nextHeaders()
|
|
18
|
+
});
|
|
19
|
+
if (!user) return {
|
|
20
|
+
success: false,
|
|
21
|
+
message: 'Not authorized to clear icon requests.'
|
|
22
|
+
};
|
|
23
|
+
if (!payload.collections?.[ICON_REQUEST_SLUG]) {
|
|
24
|
+
return {
|
|
25
|
+
success: false,
|
|
26
|
+
message: 'Request tracking is not enabled.'
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const res = await payload.delete({
|
|
30
|
+
collection: ICON_REQUEST_SLUG,
|
|
31
|
+
where: {
|
|
32
|
+
id: {
|
|
33
|
+
exists: true
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
user,
|
|
37
|
+
overrideAccess: false
|
|
38
|
+
});
|
|
39
|
+
const count = res.docs?.length ?? 0;
|
|
40
|
+
return {
|
|
41
|
+
success: true,
|
|
42
|
+
message: `Cleared ${count} runtime request${count === 1 ? '' : 's'}.`
|
|
43
|
+
};
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return {
|
|
46
|
+
success: false,
|
|
47
|
+
message: error instanceof Error ? error.message : 'Failed to clear icon requests.'
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=clearIconRequests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/admin/clearIconRequests.ts"],"sourcesContent":["'use server'\n\nimport { headers as nextHeaders } from 'next/headers'\nimport type { CollectionSlug } from 'payload'\n\nimport { ICON_REQUEST_SLUG } from '../../collections/IconRequest'\nimport { getPayloadClient } from '../../lib/getPayloadClient'\n\n/**\n * Server action behind the IconSet usage panel's \"Clear runtime requests\"\n * button: deletes every row in the `iconRequest` collection so the panel's live\n * miss list starts fresh (e.g. after you've added the missing icons).\n *\n * Auth-gated to the logged-in admin via the request headers, and the delete\n * runs with `overrideAccess: false` so the collection's own access still\n * applies. A no-op (reported as such) when tracking isn't enabled.\n */\nexport async function clearIconRequests(): Promise<{ success: boolean; message: string }> {\n try {\n const payload = await getPayloadClient()\n const { user } = await payload.auth({ headers: await nextHeaders() })\n if (!user) return { success: false, message: 'Not authorized to clear icon requests.' }\n if (!(payload.collections as Record<string, unknown>)?.[ICON_REQUEST_SLUG]) {\n return { success: false, message: 'Request tracking is not enabled.' }\n }\n\n const res = await payload.delete({\n collection: ICON_REQUEST_SLUG as CollectionSlug,\n where: { id: { exists: true } },\n user,\n overrideAccess: false,\n })\n const count = res.docs?.length ?? 0\n return { success: true, message: `Cleared ${count} runtime request${count === 1 ? '' : 's'}.` }\n } catch (error) {\n return { success: false, message: error instanceof Error ? error.message : 'Failed to clear icon requests.' }\n }\n}\n"],"names":["headers","nextHeaders","ICON_REQUEST_SLUG","getPayloadClient","clearIconRequests","payload","user","auth","success","message","collections","res","delete","collection","where","id","exists","overrideAccess","count","docs","length","error","Error"],"mappings":"AAAA;AAEA,SAASA,WAAWC,WAAW,QAAQ,eAAc;AAGrD,SAASC,iBAAiB,QAAQ,mCAA+B;AACjE,SAASC,gBAAgB,QAAQ,gCAA4B;AAE7D;;;;;;;;CAQC,GACD,OAAO,eAAeC;IACpB,IAAI;QACF,MAAMC,UAAU,MAAMF;QACtB,MAAM,EAAEG,IAAI,EAAE,GAAG,MAAMD,QAAQE,IAAI,CAAC;YAAEP,SAAS,MAAMC;QAAc;QACnE,IAAI,CAACK,MAAM,OAAO;YAAEE,SAAS;YAAOC,SAAS;QAAyC;QACtF,IAAI,CAAEJ,QAAQK,WAAW,EAA8B,CAACR,kBAAkB,EAAE;YAC1E,OAAO;gBAAEM,SAAS;gBAAOC,SAAS;YAAmC;QACvE;QAEA,MAAME,MAAM,MAAMN,QAAQO,MAAM,CAAC;YAC/BC,YAAYX;YACZY,OAAO;gBAAEC,IAAI;oBAAEC,QAAQ;gBAAK;YAAE;YAC9BV;YACAW,gBAAgB;QAClB;QACA,MAAMC,QAAQP,IAAIQ,IAAI,EAAEC,UAAU;QAClC,OAAO;YAAEZ,SAAS;YAAMC,SAAS,CAAC,QAAQ,EAAES,MAAM,gBAAgB,EAAEA,UAAU,IAAI,KAAK,IAAI,CAAC,CAAC;QAAC;IAChG,EAAE,OAAOG,OAAO;QACd,OAAO;YAAEb,SAAS;YAAOC,SAASY,iBAAiBC,QAAQD,MAAMZ,OAAO,GAAG;QAAiC;IAC9G;AACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { DefaultCellComponentProps } from 'payload';
|
|
3
|
+
/** List-view Cell for the `svgString` column — a small themed preview of the icon. */
|
|
4
|
+
export declare const IconPreviewCell: React.FC<DefaultCellComponentProps>;
|
|
5
|
+
/** Edit-view UI field — the icon at a comfortable size on a theme-neutral rounded background. */
|
|
6
|
+
export declare const IconPreviewField: React.FC;
|
|
7
|
+
//# sourceMappingURL=iconPreview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iconPreview.d.ts","sourceRoot":"","sources":["../../../src/components/admin/iconPreview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAsBxD,sFAAsF;AACtF,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAG/D,CAAA;AAED,iGAAiG;AACjG,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAiBpC,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useFormFields } from "@payloadcms/ui";
|
|
4
|
+
import { extractSvgContent, extractSvgProps } from "../../lib/extractSVG.js";
|
|
5
|
+
/**
|
|
6
|
+
* Inlines a sanitized `svgString` as a real `<svg>` so the optimizer's
|
|
7
|
+
* `currentColor` fills inherit the admin theme's text color — an `<img>` of the
|
|
8
|
+
* stored file would paint black and vanish on the dark theme. Size wins over the
|
|
9
|
+
* source's intrinsic width/height since it spreads after {@link extractSvgProps}.
|
|
10
|
+
*/ const InlineSvg = ({ svg, size })=>/*#__PURE__*/ _jsx("svg", {
|
|
11
|
+
"aria-hidden": "true",
|
|
12
|
+
...extractSvgProps(svg),
|
|
13
|
+
width: size,
|
|
14
|
+
height: size,
|
|
15
|
+
style: {
|
|
16
|
+
display: 'block',
|
|
17
|
+
color: 'currentColor'
|
|
18
|
+
},
|
|
19
|
+
dangerouslySetInnerHTML: {
|
|
20
|
+
__html: extractSvgContent(svg)
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
/** List-view Cell for the `svgString` column — a small themed preview of the icon. */ export const IconPreviewCell = ({ cellData })=>{
|
|
24
|
+
const svg = typeof cellData === 'string' ? cellData : '';
|
|
25
|
+
return svg ? /*#__PURE__*/ _jsx(InlineSvg, {
|
|
26
|
+
svg: svg,
|
|
27
|
+
size: 28
|
|
28
|
+
}) : null;
|
|
29
|
+
};
|
|
30
|
+
/** Edit-view UI field — the icon at a comfortable size on a theme-neutral rounded background. */ export const IconPreviewField = ()=>{
|
|
31
|
+
const svg = useFormFields(([fields])=>fields?.svgString?.value);
|
|
32
|
+
if (typeof svg !== 'string' || !svg) return null;
|
|
33
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
34
|
+
style: {
|
|
35
|
+
display: 'inline-flex',
|
|
36
|
+
padding: '1rem',
|
|
37
|
+
marginBlockEnd: '1rem',
|
|
38
|
+
borderRadius: 'var(--style-radius-m, 4px)',
|
|
39
|
+
border: '1px solid var(--theme-elevation-150)',
|
|
40
|
+
background: 'var(--theme-elevation-50)'
|
|
41
|
+
},
|
|
42
|
+
children: /*#__PURE__*/ _jsx(InlineSvg, {
|
|
43
|
+
svg: svg,
|
|
44
|
+
size: 64
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=iconPreview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/admin/iconPreview.tsx"],"sourcesContent":["'use client'\n\nimport type React from 'react'\nimport type { DefaultCellComponentProps } from 'payload'\nimport { useFormFields } from '@payloadcms/ui'\n\nimport { extractSvgContent, extractSvgProps } from '../../lib/extractSVG'\n\n/**\n * Inlines a sanitized `svgString` as a real `<svg>` so the optimizer's\n * `currentColor` fills inherit the admin theme's text color — an `<img>` of the\n * stored file would paint black and vanish on the dark theme. Size wins over the\n * source's intrinsic width/height since it spreads after {@link extractSvgProps}.\n */\nconst InlineSvg: React.FC<{ svg: string; size: number }> = ({ svg, size }) => (\n <svg\n aria-hidden=\"true\"\n {...extractSvgProps(svg)}\n width={size}\n height={size}\n style={{ display: 'block', color: 'currentColor' }}\n dangerouslySetInnerHTML={{ __html: extractSvgContent(svg) }}\n />\n)\n\n/** List-view Cell for the `svgString` column — a small themed preview of the icon. */\nexport const IconPreviewCell: React.FC<DefaultCellComponentProps> = ({ cellData }) => {\n const svg = typeof cellData === 'string' ? cellData : ''\n return svg ? <InlineSvg svg={svg} size={28} /> : null\n}\n\n/** Edit-view UI field — the icon at a comfortable size on a theme-neutral rounded background. */\nexport const IconPreviewField: React.FC = () => {\n const svg = useFormFields(([fields]) => fields?.svgString?.value)\n if (typeof svg !== 'string' || !svg) return null\n return (\n <div\n style={{\n display: 'inline-flex',\n padding: '1rem',\n marginBlockEnd: '1rem',\n borderRadius: 'var(--style-radius-m, 4px)',\n border: '1px solid var(--theme-elevation-150)',\n background: 'var(--theme-elevation-50)',\n }}\n >\n <InlineSvg svg={svg} size={64} />\n </div>\n )\n}\n"],"names":["useFormFields","extractSvgContent","extractSvgProps","InlineSvg","svg","size","aria-hidden","width","height","style","display","color","dangerouslySetInnerHTML","__html","IconPreviewCell","cellData","IconPreviewField","fields","svgString","value","div","padding","marginBlockEnd","borderRadius","border","background"],"mappings":"AAAA;;AAIA,SAASA,aAAa,QAAQ,iBAAgB;AAE9C,SAASC,iBAAiB,EAAEC,eAAe,QAAQ,0BAAsB;AAEzE;;;;;CAKC,GACD,MAAMC,YAAqD,CAAC,EAAEC,GAAG,EAAEC,IAAI,EAAE,iBACvE,KAACD;QACCE,eAAY;QACX,GAAGJ,gBAAgBE,IAAI;QACxBG,OAAOF;QACPG,QAAQH;QACRI,OAAO;YAAEC,SAAS;YAASC,OAAO;QAAe;QACjDC,yBAAyB;YAAEC,QAAQZ,kBAAkBG;QAAK;;AAI9D,oFAAoF,GACpF,OAAO,MAAMU,kBAAuD,CAAC,EAAEC,QAAQ,EAAE;IAC/E,MAAMX,MAAM,OAAOW,aAAa,WAAWA,WAAW;IACtD,OAAOX,oBAAM,KAACD;QAAUC,KAAKA;QAAKC,MAAM;SAAS;AACnD,EAAC;AAED,+FAA+F,GAC/F,OAAO,MAAMW,mBAA6B;IACxC,MAAMZ,MAAMJ,cAAc,CAAC,CAACiB,OAAO,GAAKA,QAAQC,WAAWC;IAC3D,IAAI,OAAOf,QAAQ,YAAY,CAACA,KAAK,OAAO;IAC5C,qBACE,KAACgB;QACCX,OAAO;YACLC,SAAS;YACTW,SAAS;YACTC,gBAAgB;YAChBC,cAAc;YACdC,QAAQ;YACRC,YAAY;QACd;kBAEA,cAAA,KAACtB;YAAUC,KAAKA;YAAKC,MAAM;;;AAGjC,EAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** RowLabel for each `iconsArray` entry — shows the row number and the icon's
|
|
2
|
+
* Title-cased name (or an "Add Name" prompt for an empty row). */
|
|
3
|
+
declare const IconRowLabel: {
|
|
4
|
+
(): import("react").JSX.Element;
|
|
5
|
+
displayName: string;
|
|
6
|
+
};
|
|
7
|
+
export default IconRowLabel;
|
|
8
|
+
//# sourceMappingURL=iconRowLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iconRowLabel.d.ts","sourceRoot":"","sources":["../../../src/components/admin/iconRowLabel.tsx"],"names":[],"mappings":"AAWA;mEACmE;AACnE,QAAA,MAAM,YAAY;;;CAiBjB,CAAA;AAID,eAAe,YAAY,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Pill, RowLabel, useRowLabel } from "@payloadcms/ui";
|
|
4
|
+
import { toTitleCase } from "../../lib/titleCase.js";
|
|
5
|
+
/** RowLabel for each `iconsArray` entry — shows the row number and the icon's
|
|
6
|
+
* Title-cased name (or an "Add Name" prompt for an empty row). */ const IconRowLabel = ()=>{
|
|
7
|
+
const { data, path, rowNumber } = useRowLabel();
|
|
8
|
+
return /*#__PURE__*/ _jsx(RowLabel, {
|
|
9
|
+
path: path,
|
|
10
|
+
rowNumber: rowNumber,
|
|
11
|
+
label: /*#__PURE__*/ _jsxs(_Fragment, {
|
|
12
|
+
children: [
|
|
13
|
+
/*#__PURE__*/ _jsx("span", {
|
|
14
|
+
children: rowNumber
|
|
15
|
+
}),
|
|
16
|
+
/*#__PURE__*/ _jsx(Pill, {
|
|
17
|
+
pillStyle: "white",
|
|
18
|
+
size: "small",
|
|
19
|
+
children: toTitleCase(data?.name) || 'Add Name'
|
|
20
|
+
})
|
|
21
|
+
]
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
IconRowLabel.displayName = 'IconRowLabel';
|
|
26
|
+
export default IconRowLabel;
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=iconRowLabel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/admin/iconRowLabel.tsx"],"sourcesContent":["'use client'\n\nimport { Pill, RowLabel, useRowLabel } from '@payloadcms/ui'\n\nimport { toTitleCase } from '../../lib/titleCase'\n\ninterface IconRowData {\n name?: string\n icon?: string | number | { id: string | number }\n}\n\n/** RowLabel for each `iconsArray` entry — shows the row number and the icon's\n * Title-cased name (or an \"Add Name\" prompt for an empty row). */\nconst IconRowLabel = () => {\n const { data, path, rowNumber } = useRowLabel<IconRowData>()\n\n return (\n <RowLabel\n path={path}\n rowNumber={rowNumber}\n label={\n <>\n <span>{rowNumber}</span>\n <Pill pillStyle=\"white\" size=\"small\">\n {toTitleCase(data?.name) || 'Add Name'}\n </Pill>\n </>\n }\n />\n )\n}\n\nIconRowLabel.displayName = 'IconRowLabel'\n\nexport default IconRowLabel\n"],"names":["Pill","RowLabel","useRowLabel","toTitleCase","IconRowLabel","data","path","rowNumber","label","span","pillStyle","size","name","displayName"],"mappings":"AAAA;;AAEA,SAASA,IAAI,EAAEC,QAAQ,EAAEC,WAAW,QAAQ,iBAAgB;AAE5D,SAASC,WAAW,QAAQ,yBAAqB;AAOjD;iEACiE,GACjE,MAAMC,eAAe;IACnB,MAAM,EAAEC,IAAI,EAAEC,IAAI,EAAEC,SAAS,EAAE,GAAGL;IAElC,qBACE,KAACD;QACCK,MAAMA;QACNC,WAAWA;QACXC,qBACE;;8BACE,KAACC;8BAAMF;;8BACP,KAACP;oBAAKU,WAAU;oBAAQC,MAAK;8BAC1BR,YAAYE,MAAMO,SAAS;;;;;AAMxC;AAEAR,aAAaS,WAAW,GAAG;AAE3B,eAAeT,aAAY"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { IconUsageManifest } from '../../scan/types';
|
|
3
|
+
/** A name requested at runtime that didn't resolve (from the `iconRequest` collection). */
|
|
4
|
+
export interface LiveRequest {
|
|
5
|
+
name: string;
|
|
6
|
+
count: number;
|
|
7
|
+
lastRequestedAt: string | null;
|
|
8
|
+
}
|
|
9
|
+
export interface IconUsagePanelClientProps {
|
|
10
|
+
/** The build-time manifest, or `null` when it hasn't been generated yet. */
|
|
11
|
+
manifest: IconUsageManifest | null;
|
|
12
|
+
/** CLI command shown in the empty state so the editor knows how to populate it. */
|
|
13
|
+
scanCommand: string;
|
|
14
|
+
/** Runtime misses recorded in production (empty unless `trackRequests` is on). */
|
|
15
|
+
liveRequests: LiveRequest[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Three-way compare for the IconSet edit view: the names this repo requests in
|
|
19
|
+
* code (the build-time manifest), the names actually requested in production
|
|
20
|
+
* that didn't resolve (the `iconRequest` collection), and the names defined in
|
|
21
|
+
* the set being edited (live form state). Adding a row clears its "missing"
|
|
22
|
+
* badge immediately.
|
|
23
|
+
*/
|
|
24
|
+
export declare const IconUsagePanelClient: React.FC<IconUsagePanelClientProps>;
|
|
25
|
+
export default IconUsagePanelClient;
|
|
26
|
+
//# sourceMappingURL=iconUsagePanel.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iconUsagePanel.client.d.ts","sourceRoot":"","sources":["../../../src/components/admin/iconUsagePanel.client.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,KAAK,EAAa,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAOpE,2FAA2F;AAC3F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAClC,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAA;IACnB,kFAAkF;IAClF,YAAY,EAAE,WAAW,EAAE,CAAA;CAC5B;AAmCD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA0IpE,CAAA;AAED,eAAe,oBAAoB,CAAA"}
|