@proveanything/smartlinks-utils-ui 1.13.7 → 1.13.11
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 +14 -6
- package/dist/{chunk-OTJV62XV.js → chunk-5ZQT2GGU.js} +5 -5
- package/dist/chunk-5ZQT2GGU.js.map +1 -0
- package/dist/{chunk-WLN4WW7K.js → chunk-7RWLFKHC.js} +505 -40
- package/dist/chunk-7RWLFKHC.js.map +1 -0
- package/dist/{chunk-7UBXTFZQ.js → chunk-A4YZYKWT.js} +9 -8
- package/dist/chunk-A4YZYKWT.js.map +1 -0
- package/dist/{chunk-4LHF5JB7.js → chunk-DH5HG5DW.js} +15 -6
- package/dist/chunk-DH5HG5DW.js.map +1 -0
- package/dist/{chunk-JMCV6FOW.js → chunk-WVCNIX7N.js} +3 -3
- package/dist/{chunk-JMCV6FOW.js.map → chunk-WVCNIX7N.js.map} +1 -1
- package/dist/components/AssetPicker/index.css +34 -0
- package/dist/components/AssetPicker/index.css.map +1 -1
- package/dist/components/AssetPicker/index.js +1 -1
- package/dist/components/ConditionsEditor/index.css +34 -0
- package/dist/components/ConditionsEditor/index.css.map +1 -1
- package/dist/components/ConditionsEditor/index.d.ts +2 -2
- package/dist/components/ConditionsEditor/index.js +2 -2
- package/dist/components/FacetRuleEditor/index.d.ts +1 -1
- package/dist/components/FacetRuleEditor/index.js +2 -2
- package/dist/components/FontPicker/index.css +34 -0
- package/dist/components/FontPicker/index.css.map +1 -1
- package/dist/components/FontPicker/index.js +1 -1
- package/dist/components/IconPicker/index.css +34 -0
- package/dist/components/IconPicker/index.css.map +1 -1
- package/dist/components/LinkPicker/index.css +34 -0
- package/dist/components/LinkPicker/index.css.map +1 -1
- package/dist/components/RecordsAdmin/index.css +34 -0
- package/dist/components/RecordsAdmin/index.css.map +1 -1
- package/dist/components/RecordsAdmin/index.d.ts +6 -2
- package/dist/components/RecordsAdmin/index.js +4 -3
- package/dist/components/RecordsAdmin/index.js.map +1 -1
- package/dist/index.css +34 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +5 -5
- package/dist/{types-a2DdgZ2H.d.ts → types-BLqki3Zy.d.ts} +11 -0
- package/package.json +3 -3
- package/dist/chunk-4LHF5JB7.js.map +0 -1
- package/dist/chunk-7UBXTFZQ.js.map +0 -1
- package/dist/chunk-OTJV62XV.js.map +0 -1
- package/dist/chunk-WLN4WW7K.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Reusable React components for [SmartLinks](https://smartlinks.app) microapps —
|
|
4
4
|
the headline module is **RecordsAdminShell**, a complete admin UI for the
|
|
5
|
-
`app.records` pattern (
|
|
6
|
-
|
|
7
|
-
and Conditions Editor.
|
|
5
|
+
`app.records` pattern (global / rule-targeted / per-product data with
|
|
6
|
+
automatic variant & batch drill-down where the collection supports them).
|
|
7
|
+
Also ships an Asset Picker, Icon Picker, Font Picker, and Conditions Editor.
|
|
8
8
|
|
|
9
9
|
- Package: `@proveanything/smartlinks-utils-ui`
|
|
10
10
|
- Tracks: `@proveanything/smartlinks ≥ 1.9`
|
|
@@ -42,7 +42,7 @@ Components inherit your shadcn-compatible CSS variables (`--primary`,
|
|
|
42
42
|
|
|
43
43
|
| Subpath | Module | Use when |
|
|
44
44
|
|---------|--------|----------|
|
|
45
|
-
| `/records-admin` | **RecordsAdminShell** + hooks (`useResolvedRecord`, `useRecordEditor`, …) | Building any
|
|
45
|
+
| `/records-admin` | **RecordsAdminShell** + hooks (`useResolvedRecord`, `useRecordEditor`, …) | Building any global / rule-targeted / per-product admin (variant & batch drill-down is automatic) |
|
|
46
46
|
| `/asset-picker` | AssetPicker | Pick / upload / paste / URL-import media assets |
|
|
47
47
|
| `/icon-picker` | IconPicker | Searchable Font Awesome 7 Pro picker |
|
|
48
48
|
| `/font-picker` | FontPicker | Google Fonts + custom uploaded fonts |
|
|
@@ -58,6 +58,14 @@ Each module has a full reference doc under [`docs/`](./docs/README.md):
|
|
|
58
58
|
|
|
59
59
|
### Records Admin Shell
|
|
60
60
|
|
|
61
|
+
> ⚠️ **Before you mount the shell, decide cardinality.** If your app is a
|
|
62
|
+
> list of things (auction items, FAQs, image gallery, perks) you want
|
|
63
|
+
> `items.cardinality: 'list'`. If it's one winning record per scope
|
|
64
|
+
> (warranty, nutrition, care instructions) keep the default `'singleton'`.
|
|
65
|
+
> The default is `'singleton'`, so multi-item apps **must opt in** — see
|
|
66
|
+
> [Choosing cardinality](./docs/records-admin-shell.md#-choosing-cardinality-read-this-first).
|
|
67
|
+
> (`'collection'` is still accepted as a deprecated alias for `'list'`.)
|
|
68
|
+
|
|
61
69
|
```tsx
|
|
62
70
|
import {
|
|
63
71
|
RecordsAdminShell,
|
|
@@ -71,7 +79,7 @@ import * as SL from '@proveanything/smartlinks';
|
|
|
71
79
|
appId={appId}
|
|
72
80
|
recordType="nutrition"
|
|
73
81
|
label="Nutrition info"
|
|
74
|
-
scopes={['
|
|
82
|
+
scopes={['collection', 'rule', 'product']}
|
|
75
83
|
contextScope={{ productId, variantId, batchId }} // optional, from iframe URL
|
|
76
84
|
defaultData={() => ({})}
|
|
77
85
|
renderEditor={(ctx) => <NutritionForm ctx={ctx} />}
|
|
@@ -92,7 +100,7 @@ const { data, source, isLoading } = useResolvedRecord({
|
|
|
92
100
|
SL, appId, recordType: 'nutrition',
|
|
93
101
|
collectionId, productId, variantId, batchId,
|
|
94
102
|
});
|
|
95
|
-
// source: 'proof' | 'batch' | 'variant' | 'product' | '
|
|
103
|
+
// source: 'proof' | 'batch' | 'variant' | 'product' | 'rule' | 'collection' | null
|
|
96
104
|
```
|
|
97
105
|
|
|
98
106
|
### Asset Picker
|
|
@@ -233,7 +233,7 @@ function useFontSearch(options = {}) {
|
|
|
233
233
|
const config = await sl.appConfiguration.getConfig({
|
|
234
234
|
collectionId: scope.collectionId,
|
|
235
235
|
appId: fontsConfigAppId,
|
|
236
|
-
|
|
236
|
+
admin: true
|
|
237
237
|
});
|
|
238
238
|
if (cancelled) return;
|
|
239
239
|
const fontsConfig = config || { fonts: [] };
|
|
@@ -260,7 +260,7 @@ function useFontSearch(options = {}) {
|
|
|
260
260
|
collectionId: scope.collectionId,
|
|
261
261
|
appId: fontsConfigAppId,
|
|
262
262
|
config: { fonts: families },
|
|
263
|
-
|
|
263
|
+
admin: true
|
|
264
264
|
});
|
|
265
265
|
} catch (err) {
|
|
266
266
|
console.error("[FontPicker] Failed to save custom fonts config:", err);
|
|
@@ -314,7 +314,7 @@ function useFontSearch(options = {}) {
|
|
|
314
314
|
file,
|
|
315
315
|
scope: scopeObj,
|
|
316
316
|
name: file.name,
|
|
317
|
-
|
|
317
|
+
admin: true,
|
|
318
318
|
onProgress: (pct) => setUploadProgress(pct)
|
|
319
319
|
});
|
|
320
320
|
const style = {
|
|
@@ -1086,5 +1086,5 @@ var FontPicker = (props) => {
|
|
|
1086
1086
|
};
|
|
1087
1087
|
|
|
1088
1088
|
export { CATEGORY_FALLBACKS, CATEGORY_LABELS, FontPicker, GOOGLE_FONTS_CATALOG, getGoogleFontUrl };
|
|
1089
|
-
//# sourceMappingURL=chunk-
|
|
1090
|
-
//# sourceMappingURL=chunk-
|
|
1089
|
+
//# sourceMappingURL=chunk-5ZQT2GGU.js.map
|
|
1090
|
+
//# sourceMappingURL=chunk-5ZQT2GGU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/FontPicker/google-fonts.ts","../src/components/FontPicker/useFontSearch.ts","../src/components/FontPicker/FontUploadZone.tsx","../src/components/FontPicker/FontStyleEditor.tsx","../src/components/FontPicker/FontPicker.tsx"],"names":["useState","useRef","useCallback","jsxs","jsx","useEffect","Upload","Check","Loader2","Fragment","X"],"mappings":"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","file":"chunk-5ZQT2GGU.js","sourcesContent":["// =============================================================================\r\n// FONT PICKER — Google Fonts Catalog\r\n// =============================================================================\r\n// Curated list of popular Google Fonts with proper metadata.\r\n// Each entry includes the exact Google Fonts CSS URL for loading.\r\n// =============================================================================\r\n\r\nimport type { FontEntry, FontCategory, FontWeight } from './types';\r\n\r\n/** Helper to build a Google Fonts CSS URL */\r\nconst gUrl = (family: string, weights: FontWeight[] = [300, 400, 500, 600, 700]): string => {\r\n const encoded = family.replace(/ /g, '+');\r\n const wStr = weights.join(';');\r\n return `https://fonts.googleapis.com/css2?family=${encoded}:wght@${wStr}&display=swap`;\r\n};\r\n\r\ninterface FontDef {\r\n family: string;\r\n category: FontCategory;\r\n weights?: FontWeight[];\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Curated font list — ~120 popular Google Fonts across all categories\r\n// ---------------------------------------------------------------------------\r\nconst FONT_DEFS: FontDef[] = [\r\n // Sans-Serif\r\n { family: 'Inter', category: 'sans-serif' },\r\n { family: 'Roboto', category: 'sans-serif' },\r\n { family: 'Open Sans', category: 'sans-serif' },\r\n { family: 'Lato', category: 'sans-serif' },\r\n { family: 'Montserrat', category: 'sans-serif' },\r\n { family: 'Poppins', category: 'sans-serif' },\r\n { family: 'Nunito', category: 'sans-serif' },\r\n { family: 'Raleway', category: 'sans-serif' },\r\n { family: 'Work Sans', category: 'sans-serif' },\r\n { family: 'DM Sans', category: 'sans-serif' },\r\n { family: 'Manrope', category: 'sans-serif' },\r\n { family: 'Plus Jakarta Sans', category: 'sans-serif' },\r\n { family: 'Space Grotesk', category: 'sans-serif' },\r\n { family: 'Outfit', category: 'sans-serif' },\r\n { family: 'Sora', category: 'sans-serif' },\r\n { family: 'Figtree', category: 'sans-serif' },\r\n { family: 'Albert Sans', category: 'sans-serif' },\r\n { family: 'Urbanist', category: 'sans-serif' },\r\n { family: 'Lexend', category: 'sans-serif' },\r\n { family: 'Red Hat Display', category: 'sans-serif' },\r\n { family: 'Instrument Sans', category: 'sans-serif' },\r\n { family: 'Geist', category: 'sans-serif', weights: [400, 500, 600, 700] },\r\n { family: 'Onest', category: 'sans-serif' },\r\n { family: 'General Sans', category: 'sans-serif', weights: [400, 500, 600, 700] },\r\n { family: 'Satoshi', category: 'sans-serif', weights: [400, 500, 700] },\r\n { family: 'Cabinet Grotesk', category: 'sans-serif', weights: [400, 500, 700, 800] },\r\n { family: 'Switzer', category: 'sans-serif', weights: [400, 500, 600, 700] },\r\n { family: 'Overpass', category: 'sans-serif' },\r\n { family: 'Nunito Sans', category: 'sans-serif' },\r\n { family: 'Source Sans 3', category: 'sans-serif' },\r\n { family: 'PT Sans', category: 'sans-serif', weights: [400, 700] },\r\n { family: 'Rubik', category: 'sans-serif' },\r\n { family: 'Noto Sans', category: 'sans-serif' },\r\n { family: 'Karla', category: 'sans-serif' },\r\n { family: 'Mukta', category: 'sans-serif' },\r\n { family: 'Libre Franklin', category: 'sans-serif' },\r\n { family: 'Barlow', category: 'sans-serif' },\r\n { family: 'Josefin Sans', category: 'sans-serif' },\r\n { family: 'Quicksand', category: 'sans-serif' },\r\n { family: 'Exo 2', category: 'sans-serif' },\r\n { family: 'Mulish', category: 'sans-serif' },\r\n { family: 'Cabin', category: 'sans-serif' },\r\n { family: 'Archivo', category: 'sans-serif' },\r\n { family: 'Catamaran', category: 'sans-serif' },\r\n { family: 'Hind', category: 'sans-serif' },\r\n { family: 'Asap', category: 'sans-serif' },\r\n\r\n // Serif\r\n { family: 'Playfair Display', category: 'serif' },\r\n { family: 'Merriweather', category: 'serif' },\r\n { family: 'Lora', category: 'serif' },\r\n { family: 'Source Serif 4', category: 'serif' },\r\n { family: 'PT Serif', category: 'serif', weights: [400, 700] },\r\n { family: 'Noto Serif', category: 'serif' },\r\n { family: 'Crimson Text', category: 'serif', weights: [400, 600, 700] },\r\n { family: 'Libre Baskerville', category: 'serif', weights: [400, 700] },\r\n { family: 'DM Serif Display', category: 'serif', weights: [400] },\r\n { family: 'DM Serif Text', category: 'serif', weights: [400] },\r\n { family: 'Cormorant Garamond', category: 'serif' },\r\n { family: 'EB Garamond', category: 'serif' },\r\n { family: 'Bitter', category: 'serif' },\r\n { family: 'Vollkorn', category: 'serif' },\r\n { family: 'Spectral', category: 'serif' },\r\n { family: 'Fraunces', category: 'serif' },\r\n { family: 'Newsreader', category: 'serif' },\r\n { family: 'Instrument Serif', category: 'serif', weights: [400] },\r\n { family: 'Literata', category: 'serif' },\r\n { family: 'Brygada 1918', category: 'serif' },\r\n { family: 'Bodoni Moda', category: 'serif' },\r\n { family: 'Cardo', category: 'serif', weights: [400, 700] },\r\n { family: 'Baskervville', category: 'serif', weights: [400] },\r\n { family: 'Cormorant', category: 'serif' },\r\n { family: 'Young Serif', category: 'serif', weights: [400] },\r\n\r\n // Display\r\n { family: 'Bebas Neue', category: 'display', weights: [400] },\r\n { family: 'Oswald', category: 'display' },\r\n { family: 'Righteous', category: 'display', weights: [400] },\r\n { family: 'Alfa Slab One', category: 'display', weights: [400] },\r\n { family: 'Abril Fatface', category: 'display', weights: [400] },\r\n { family: 'Lobster', category: 'display', weights: [400] },\r\n { family: 'Comfortaa', category: 'display' },\r\n { family: 'Fredoka', category: 'display' },\r\n { family: 'Titan One', category: 'display', weights: [400] },\r\n { family: 'Bungee', category: 'display', weights: [400] },\r\n { family: 'Secular One', category: 'display', weights: [400] },\r\n { family: 'Lilita One', category: 'display', weights: [400] },\r\n { family: 'Passion One', category: 'display', weights: [400, 700] },\r\n { family: 'Fugaz One', category: 'display', weights: [400] },\r\n { family: 'Russo One', category: 'display', weights: [400] },\r\n { family: 'Paytone One', category: 'display', weights: [400] },\r\n { family: 'Black Ops One', category: 'display', weights: [400] },\r\n { family: 'Permanent Marker', category: 'display', weights: [400] },\r\n { family: 'Shrikhand', category: 'display', weights: [400] },\r\n { family: 'Chivo', category: 'display' },\r\n { family: 'Staatliches', category: 'display', weights: [400] },\r\n\r\n // Handwriting\r\n { family: 'Dancing Script', category: 'handwriting' },\r\n { family: 'Pacifico', category: 'handwriting', weights: [400] },\r\n { family: 'Caveat', category: 'handwriting' },\r\n { family: 'Satisfy', category: 'handwriting', weights: [400] },\r\n { family: 'Great Vibes', category: 'handwriting', weights: [400] },\r\n { family: 'Sacramento', category: 'handwriting', weights: [400] },\r\n { family: 'Kalam', category: 'handwriting' },\r\n { family: 'Indie Flower', category: 'handwriting', weights: [400] },\r\n { family: 'Shadows Into Light', category: 'handwriting', weights: [400] },\r\n { family: 'Amatic SC', category: 'handwriting', weights: [400, 700] },\r\n { family: 'Handlee', category: 'handwriting', weights: [400] },\r\n { family: 'Patrick Hand', category: 'handwriting', weights: [400] },\r\n { family: 'Architects Daughter', category: 'handwriting', weights: [400] },\r\n { family: 'Courgette', category: 'handwriting', weights: [400] },\r\n { family: 'Cookie', category: 'handwriting', weights: [400] },\r\n\r\n // Monospace\r\n { family: 'JetBrains Mono', category: 'monospace' },\r\n { family: 'Fira Code', category: 'monospace' },\r\n { family: 'Source Code Pro', category: 'monospace' },\r\n { family: 'Roboto Mono', category: 'monospace' },\r\n { family: 'Space Mono', category: 'monospace', weights: [400, 700] },\r\n { family: 'IBM Plex Mono', category: 'monospace' },\r\n { family: 'Inconsolata', category: 'monospace' },\r\n { family: 'Ubuntu Mono', category: 'monospace', weights: [400, 700] },\r\n { family: 'Red Hat Mono', category: 'monospace' },\r\n { family: 'Courier Prime', category: 'monospace', weights: [400, 700] },\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// Build catalog\r\n// ---------------------------------------------------------------------------\r\n\r\nconst DEFAULT_WEIGHTS: FontWeight[] = [300, 400, 500, 600, 700];\r\n\r\nexport const GOOGLE_FONTS_CATALOG: FontEntry[] = FONT_DEFS.map((def) => {\r\n const weights = def.weights || DEFAULT_WEIGHTS;\r\n return {\r\n family: def.family,\r\n source: 'google' as const,\r\n category: def.category,\r\n weights,\r\n loadUrl: gUrl(def.family, weights),\r\n };\r\n});\r\n\r\n/** Get a Google Fonts CSS URL for a specific font */\r\nexport const getGoogleFontUrl = (family: string, weights?: FontWeight[]): string =>\r\n gUrl(family, weights || DEFAULT_WEIGHTS);\r\n\r\n/** Category labels for display */\r\nexport const CATEGORY_LABELS: Record<FontCategory, string> = {\r\n 'sans-serif': 'Sans Serif',\r\n serif: 'Serif',\r\n display: 'Display',\r\n handwriting: 'Handwriting',\r\n monospace: 'Monospace',\r\n};\r\n\r\n/** Fallback stacks per category */\r\nexport const CATEGORY_FALLBACKS: Record<FontCategory, string> = {\r\n 'sans-serif': 'ui-sans-serif, system-ui, sans-serif',\r\n serif: 'ui-serif, Georgia, serif',\r\n display: 'ui-sans-serif, system-ui, sans-serif',\r\n handwriting: 'cursive',\r\n monospace: 'ui-monospace, monospace',\r\n};\r\n","// =============================================================================\r\n// FONT PICKER — Search & Filter Hook\r\n// =============================================================================\r\n// Loads Google Fonts catalog + custom fonts from appConfiguration config.\r\n// Custom fonts are stored as { fonts: CustomFontFamily[] } in a config key.\r\n// =============================================================================\r\n\r\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\r\nimport type { FontEntry, FontCategory, FontScope, FontWeight, CustomFontFamily, CustomFontStyle, CustomFontsConfig } from './types';\r\nimport { GOOGLE_FONTS_CATALOG, CATEGORY_LABELS } from './google-fonts';\r\n\r\n// Dynamically import SL only when custom fonts are needed\r\nlet SL: typeof import('@proveanything/smartlinks') | null = null;\r\nconst getSL = async () => {\r\n if (!SL) SL = await import('@proveanything/smartlinks');\r\n return SL;\r\n};\r\n\r\nexport interface UseFontSearchOptions {\r\n categories?: FontCategory[];\r\n scope?: FontScope;\r\n showCustomFonts?: boolean;\r\n admin?: boolean;\r\n pageSize?: number;\r\n /** App ID for storing custom fonts config. Defaults to 'customFonts'. */\r\n fontsConfigAppId?: string;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Weight / style detection from filename\r\n// ---------------------------------------------------------------------------\r\nconst WEIGHT_PATTERNS: [RegExp, FontWeight][] = [\r\n [/\\b(hairline|thin)\\b/i, 100],\r\n [/\\b(ultra\\s?light|extra\\s?light)\\b/i, 200],\r\n [/\\blight\\b/i, 300],\r\n [/\\b(regular|normal|book)\\b/i, 400],\r\n [/\\bmedium\\b/i, 500],\r\n [/\\b(semi\\s?bold|demi\\s?bold)\\b/i, 600],\r\n [/\\bbold\\b/i, 700],\r\n [/\\b(extra\\s?bold|ultra\\s?bold)\\b/i, 800],\r\n [/\\b(black|heavy)\\b/i, 900],\r\n];\r\n\r\nexport function detectWeightFromFilename(name: string): FontWeight {\r\n for (const [pattern, weight] of WEIGHT_PATTERNS) {\r\n if (pattern.test(name)) return weight;\r\n }\r\n return 400;\r\n}\r\n\r\nexport function detectItalicFromFilename(name: string): boolean {\r\n return /\\b(italic|oblique|ital)\\b/i.test(name);\r\n}\r\n\r\n/** Extract a clean font family name from a filename */\r\nexport function fontFamilyFromFilename(name: string): string {\r\n let clean = name.replace(/\\.(woff2?|ttf|otf|eot)$/i, '');\r\n // Remove weight/style suffixes\r\n clean = clean.replace(/[-_]?(regular|bold|italic|oblique|ital|light|medium|semibold|semi-bold|demi-bold|thin|black|extra\\s?bold|extra\\s?light|ultra\\s?light|ultra\\s?bold|heavy|hairline|book|normal)/gi, '');\r\n // Replace separators with spaces\r\n clean = clean.replace(/[-_]/g, ' ').replace(/\\s+/g, ' ').trim();\r\n if (!clean) return 'Custom Font';\r\n return clean\r\n .split(' ')\r\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())\r\n .join(' ');\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Convert CustomFontFamily[] to FontEntry[] for display\r\n// ---------------------------------------------------------------------------\r\nfunction customFamiliesToEntries(families: CustomFontFamily[]): FontEntry[] {\r\n return families.map((fam) => {\r\n // Use the first font style's URL for preview\r\n const firstStyle = fam.fonts[0];\r\n return {\r\n family: fam.name,\r\n source: 'custom' as const,\r\n loadUrl: firstStyle?.url,\r\n assetId: firstStyle?.assetId,\r\n mimeType: firstStyle?.mimeType,\r\n weights: fam.fonts.map((f) => f.weight),\r\n };\r\n });\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Hook\r\n// ---------------------------------------------------------------------------\r\nexport function useFontSearch(options: UseFontSearchOptions = {}) {\r\n const {\r\n categories,\r\n scope,\r\n showCustomFonts = false,\r\n admin = false,\r\n pageSize = 50,\r\n fontsConfigAppId = 'customFonts',\r\n } = options;\r\n\r\n const [customFamilies, setCustomFamilies] = useState<CustomFontFamily[]>([]);\r\n const [customFonts, setCustomFonts] = useState<FontEntry[]>([]);\r\n const [loadingCustom, setLoadingCustom] = useState(false);\r\n const [activeTab, setActiveTab] = useState<'google' | 'custom'>('google');\r\n const [activeCategory, setActiveCategory] = useState<FontCategory | null>(null);\r\n const [query, setQuery] = useState('');\r\n const [page, setPage] = useState(0);\r\n const debounceRef = useRef<ReturnType<typeof setTimeout>>();\r\n\r\n // Load custom fonts from config\r\n useEffect(() => {\r\n if (!showCustomFonts || !scope?.collectionId) return;\r\n\r\n let cancelled = false;\r\n setLoadingCustom(true);\r\n\r\n (async () => {\r\n try {\r\n const sl = await getSL();\r\n const config = await sl.appConfiguration.getConfig({\r\n collectionId: scope.collectionId,\r\n appId: fontsConfigAppId,\r\n admin: true,\r\n });\r\n\r\n if (cancelled) return;\r\n\r\n const fontsConfig = (config as any as CustomFontsConfig) || { fonts: [] };\r\n const families = fontsConfig.fonts || [];\r\n setCustomFamilies(families);\r\n setCustomFonts(customFamiliesToEntries(families));\r\n } catch (err) {\r\n console.warn('[FontPicker] Failed to load custom fonts config:', err);\r\n setCustomFamilies([]);\r\n setCustomFonts([]);\r\n } finally {\r\n if (!cancelled) setLoadingCustom(false);\r\n }\r\n })();\r\n\r\n return () => { cancelled = true; };\r\n }, [showCustomFonts, scope?.collectionId, scope?.productId, admin, fontsConfigAppId]);\r\n\r\n // Save custom fonts config\r\n const saveCustomFonts = useCallback(async (families: CustomFontFamily[]) => {\r\n if (!scope?.collectionId) return;\r\n try {\r\n const sl = await getSL();\r\n await sl.appConfiguration.setConfig({\r\n collectionId: scope.collectionId,\r\n appId: fontsConfigAppId,\r\n config: { fonts: families } as any,\r\n admin: true,\r\n });\r\n } catch (err) {\r\n console.error('[FontPicker] Failed to save custom fonts config:', err);\r\n }\r\n }, [scope?.collectionId, admin, fontsConfigAppId]);\r\n\r\n // Debounced search\r\n const setSearch = useCallback((q: string) => {\r\n if (debounceRef.current) clearTimeout(debounceRef.current);\r\n debounceRef.current = setTimeout(() => {\r\n setQuery(q.trim().toLowerCase());\r\n setPage(0);\r\n }, 200);\r\n }, []);\r\n\r\n // Source based on active tab\r\n const source = activeTab === 'custom' ? customFonts : GOOGLE_FONTS_CATALOG;\r\n\r\n // Available categories\r\n const availableCategories = useMemo(() => {\r\n const set = new Set<FontCategory>();\r\n for (const font of GOOGLE_FONTS_CATALOG) {\r\n if (font.category) {\r\n if (!categories || categories.includes(font.category)) {\r\n set.add(font.category);\r\n }\r\n }\r\n }\r\n const order: FontCategory[] = ['sans-serif', 'serif', 'display', 'handwriting', 'monospace'];\r\n return order.filter((c) => set.has(c));\r\n }, [categories]);\r\n\r\n // Filtered results\r\n const filtered = useMemo(() => {\r\n let result = source;\r\n if (activeCategory && activeTab === 'google') {\r\n result = result.filter((f) => f.category === activeCategory);\r\n }\r\n if (query) {\r\n result = result.filter((f) => f.family.toLowerCase().includes(query));\r\n }\r\n return result;\r\n }, [source, activeCategory, activeTab, query]);\r\n\r\n const totalPages = Math.ceil(filtered.length / pageSize);\r\n const pageFonts = useMemo(\r\n () => filtered.slice(page * pageSize, (page + 1) * pageSize),\r\n [filtered, page, pageSize],\r\n );\r\n\r\n // ── Upload a font file ──\r\n const [uploading, setUploading] = useState(false);\r\n const [uploadProgress, setUploadProgress] = useState(0);\r\n\r\n const uploadFont = useCallback(async (file: File): Promise<CustomFontStyle | null> => {\r\n if (!scope?.collectionId) return null;\r\n setUploading(true);\r\n setUploadProgress(0);\r\n try {\r\n const sl = await getSL();\r\n const scopeObj = scope.productId\r\n ? { type: 'product' as const, collectionId: scope.collectionId, productId: scope.productId }\r\n : { type: 'collection' as const, collectionId: scope.collectionId };\r\n\r\n const result = await sl.asset.upload({\r\n file,\r\n scope: scopeObj,\r\n name: file.name,\r\n admin: true,\r\n onProgress: (pct: number) => setUploadProgress(pct),\r\n });\r\n\r\n const style: CustomFontStyle = {\r\n url: (result as any).url,\r\n assetId: (result as any).id,\r\n weight: detectWeightFromFilename(file.name),\r\n italic: detectItalicFromFilename(file.name),\r\n mimeType: file.type,\r\n fileName: file.name,\r\n };\r\n\r\n return style;\r\n } catch (err) {\r\n console.error('[FontPicker] Upload failed:', err);\r\n return null;\r\n } finally {\r\n setUploading(false);\r\n setUploadProgress(0);\r\n }\r\n }, [scope?.collectionId, scope?.productId, admin]);\r\n\r\n // ── Add a font style to a family (or create new family) ──\r\n const addFontStyle = useCallback(async (familyName: string, style: CustomFontStyle) => {\r\n const updated = [...customFamilies];\r\n const existing = updated.find((f) => f.name === familyName);\r\n if (existing) {\r\n existing.fonts.push(style);\r\n } else {\r\n updated.push({ name: familyName, fonts: [style] });\r\n }\r\n setCustomFamilies(updated);\r\n setCustomFonts(customFamiliesToEntries(updated));\r\n await saveCustomFonts(updated);\r\n }, [customFamilies, saveCustomFonts]);\r\n\r\n // ── Update a font family ──\r\n const updateFontFamily = useCallback(async (index: number, family: CustomFontFamily) => {\r\n const updated = [...customFamilies];\r\n updated[index] = family;\r\n setCustomFamilies(updated);\r\n setCustomFonts(customFamiliesToEntries(updated));\r\n await saveCustomFonts(updated);\r\n }, [customFamilies, saveCustomFonts]);\r\n\r\n // ── Delete a font family ──\r\n const deleteFontFamily = useCallback(async (index: number) => {\r\n const updated = customFamilies.filter((_, i) => i !== index);\r\n setCustomFamilies(updated);\r\n setCustomFonts(customFamiliesToEntries(updated));\r\n await saveCustomFonts(updated);\r\n }, [customFamilies, saveCustomFonts]);\r\n\r\n // ── Delete a single style from a family ──\r\n const deleteFontStyle = useCallback(async (familyIndex: number, styleIndex: number) => {\r\n const updated = [...customFamilies];\r\n const family = { ...updated[familyIndex], fonts: [...updated[familyIndex].fonts] };\r\n family.fonts.splice(styleIndex, 1);\r\n if (family.fonts.length === 0) {\r\n updated.splice(familyIndex, 1);\r\n } else {\r\n updated[familyIndex] = family;\r\n }\r\n setCustomFamilies(updated);\r\n setCustomFonts(customFamiliesToEntries(updated));\r\n await saveCustomFonts(updated);\r\n }, [customFamilies, saveCustomFonts]);\r\n\r\n return {\r\n loading: loadingCustom,\r\n query,\r\n setSearch,\r\n activeTab,\r\n setActiveTab: useCallback((t: 'google' | 'custom') => {\r\n setActiveTab(t);\r\n setPage(0);\r\n }, []),\r\n hasCustomFonts: showCustomFonts && !!scope?.collectionId,\r\n customFontCount: customFamilies.length,\r\n customFamilies,\r\n activeCategory,\r\n setActiveCategory: useCallback((c: FontCategory | null) => {\r\n setActiveCategory(c);\r\n setPage(0);\r\n }, []),\r\n availableCategories,\r\n filtered,\r\n pageFonts,\r\n page,\r\n setPage,\r\n totalPages,\r\n totalCount: filtered.length,\r\n categoryLabels: CATEGORY_LABELS,\r\n uploading,\r\n uploadProgress,\r\n uploadFont,\r\n addFontStyle,\r\n updateFontFamily,\r\n deleteFontFamily,\r\n deleteFontStyle,\r\n };\r\n}\r\n","// =============================================================================\r\n// FONT PICKER — Upload Zone\r\n// =============================================================================\r\n// Drag-and-drop zone for uploading custom font files (.woff2, .ttf, .otf, .woff)\r\n\r\nimport React, { useState, useCallback, useRef } from 'react';\r\nimport { cn } from '../../utils/cn';\r\nimport { Upload, Loader2, CheckCircle2, AlertCircle } from 'lucide-react';\r\n\r\nconst ACCEPTED_EXTENSIONS = '.woff,.woff2,.ttf,.otf';\r\nconst ACCEPTED_MIME_TYPES = [\r\n 'font/woff', 'font/woff2', 'font/ttf', 'font/otf', 'font/sfnt',\r\n 'application/font-woff', 'application/font-woff2',\r\n 'application/x-font-ttf', 'application/x-font-otf',\r\n 'application/vnd.ms-opentype',\r\n // browsers often report these generically\r\n 'application/octet-stream', '',\r\n];\r\n\r\nfunction isValidFontFile(file: File): boolean {\r\n const ext = file.name.toLowerCase().split('.').pop();\r\n return ['woff', 'woff2', 'ttf', 'otf'].includes(ext || '');\r\n}\r\n\r\ninterface FontUploadZoneProps {\r\n uploading: boolean;\r\n uploadProgress: number;\r\n onUpload: (file: File) => Promise<any>;\r\n className?: string;\r\n}\r\n\r\nexport const FontUploadZone: React.FC<FontUploadZoneProps> = ({\r\n uploading,\r\n uploadProgress,\r\n onUpload,\r\n className,\r\n}) => {\r\n const [dragOver, setDragOver] = useState(false);\r\n const [status, setStatus] = useState<'idle' | 'success' | 'error'>('idle');\r\n const [errorMsg, setErrorMsg] = useState('');\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n\r\n const handleFile = useCallback(async (file: File) => {\r\n if (!isValidFontFile(file)) {\r\n setStatus('error');\r\n setErrorMsg('Unsupported format. Use .woff2, .ttf, .otf, or .woff');\r\n setTimeout(() => setStatus('idle'), 3000);\r\n return;\r\n }\r\n setStatus('idle');\r\n setErrorMsg('');\r\n const result = await onUpload(file);\r\n if (result) {\r\n setStatus('success');\r\n setTimeout(() => setStatus('idle'), 2000);\r\n } else {\r\n setStatus('error');\r\n setErrorMsg('Upload failed');\r\n setTimeout(() => setStatus('idle'), 3000);\r\n }\r\n }, [onUpload]);\r\n\r\n const onDrop = useCallback((e: React.DragEvent) => {\r\n e.preventDefault();\r\n setDragOver(false);\r\n const file = e.dataTransfer.files[0];\r\n if (file) handleFile(file);\r\n }, [handleFile]);\r\n\r\n const onDragOver = useCallback((e: React.DragEvent) => {\r\n e.preventDefault();\r\n setDragOver(true);\r\n }, []);\r\n\r\n const onDragLeave = useCallback(() => setDragOver(false), []);\r\n\r\n const onInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\r\n const file = e.target.files?.[0];\r\n if (file) handleFile(file);\r\n if (inputRef.current) inputRef.current.value = '';\r\n }, [handleFile]);\r\n\r\n return (\r\n <div\r\n onDrop={onDrop}\r\n onDragOver={onDragOver}\r\n onDragLeave={onDragLeave}\r\n onClick={() => !uploading && inputRef.current?.click()}\r\n className={cn(\r\n 'relative flex flex-col items-center justify-center gap-2 p-6 rounded-lg border-2 border-dashed cursor-pointer transition-colors',\r\n dragOver\r\n ? 'border-primary bg-primary/5'\r\n : status === 'error'\r\n ? 'border-destructive/50 bg-destructive/5'\r\n : status === 'success'\r\n ? 'border-primary/50 bg-primary/5'\r\n : 'border-border hover:border-muted-foreground/40 hover:bg-accent/30',\r\n uploading && 'pointer-events-none opacity-70',\r\n className,\r\n )}\r\n >\r\n <input\r\n ref={inputRef}\r\n type=\"file\"\r\n accept={ACCEPTED_EXTENSIONS}\r\n onChange={onInputChange}\r\n className=\"hidden\"\r\n />\r\n\r\n {uploading ? (\r\n <>\r\n <Loader2 className=\"w-6 h-6 animate-spin text-primary\" />\r\n <p className=\"text-sm text-muted-foreground\">\r\n Uploading… {uploadProgress > 0 ? `${Math.round(uploadProgress)}%` : ''}\r\n </p>\r\n {uploadProgress > 0 && (\r\n <div className=\"w-full max-w-[200px] h-1.5 bg-muted rounded-full overflow-hidden\">\r\n <div\r\n className=\"h-full bg-primary rounded-full transition-all duration-300\"\r\n style={{ width: `${uploadProgress}%` }}\r\n />\r\n </div>\r\n )}\r\n </>\r\n ) : status === 'success' ? (\r\n <>\r\n <CheckCircle2 className=\"w-6 h-6 text-primary\" />\r\n <p className=\"text-sm text-primary\">Font uploaded!</p>\r\n </>\r\n ) : status === 'error' ? (\r\n <>\r\n <AlertCircle className=\"w-6 h-6 text-destructive\" />\r\n <p className=\"text-sm text-destructive\">{errorMsg}</p>\r\n </>\r\n ) : (\r\n <>\r\n <Upload className=\"w-6 h-6 text-muted-foreground\" />\r\n <div className=\"text-center\">\r\n <p className=\"text-sm text-foreground font-medium\">\r\n Drop a font file or <span className=\"text-primary\">browse</span>\r\n </p>\r\n <p className=\"text-xs text-muted-foreground mt-0.5\">.woff2, .ttf, .otf, .woff</p>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// FONT PICKER — Font Style Editor\r\n// =============================================================================\r\n// Mini-form shown after uploading a font file to set family name, weight, italic.\r\n// Also used inline to edit existing custom font families.\r\n// =============================================================================\r\n\r\nimport React, { useState, useCallback } from 'react';\r\nimport type { FontWeight, CustomFontStyle, CustomFontFamily } from './types';\r\nimport { cn } from '../../utils/cn';\r\nimport { Trash2, Plus, ChevronDown, ChevronUp, Edit2, Check, X } from 'lucide-react';\r\n\r\nconst WEIGHT_OPTIONS: { value: FontWeight; label: string }[] = [\r\n { value: 100, label: 'Thin (100)' },\r\n { value: 200, label: 'Extra Light (200)' },\r\n { value: 300, label: 'Light (300)' },\r\n { value: 400, label: 'Regular (400)' },\r\n { value: 500, label: 'Medium (500)' },\r\n { value: 600, label: 'Semi Bold (600)' },\r\n { value: 700, label: 'Bold (700)' },\r\n { value: 800, label: 'Extra Bold (800)' },\r\n { value: 900, label: 'Black (900)' },\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// Post-upload form: set family name + confirm weight/italic\r\n// ---------------------------------------------------------------------------\r\ninterface UploadFormProps {\r\n /** The auto-detected family name */\r\n defaultFamilyName: string;\r\n /** The auto-detected style from the filename */\r\n style: CustomFontStyle;\r\n /** Existing family names to suggest adding to */\r\n existingFamilies: string[];\r\n /** Called when user confirms */\r\n onConfirm: (familyName: string, style: CustomFontStyle) => void;\r\n /** Called when user cancels */\r\n onCancel: () => void;\r\n className?: string;\r\n}\r\n\r\nexport const FontUploadForm: React.FC<UploadFormProps> = ({\r\n defaultFamilyName,\r\n style,\r\n existingFamilies,\r\n onConfirm,\r\n onCancel,\r\n className,\r\n}) => {\r\n const [familyName, setFamilyName] = useState(defaultFamilyName);\r\n const [weight, setWeight] = useState<FontWeight>(style.weight);\r\n const [italic, setItalic] = useState(style.italic);\r\n\r\n const handleConfirm = useCallback(() => {\r\n if (!familyName.trim()) return;\r\n onConfirm(familyName.trim(), { ...style, weight, italic });\r\n }, [familyName, weight, italic, style, onConfirm]);\r\n\r\n return (\r\n <div className={cn('rounded-lg border border-border bg-card p-4 space-y-3', className)}>\r\n <p className=\"text-xs font-semibold text-foreground uppercase tracking-wide\">New Font Style</p>\r\n\r\n {/* Family name */}\r\n <div className=\"space-y-1\">\r\n <label className=\"text-xs text-muted-foreground\">Font Family Name</label>\r\n <input\r\n type=\"text\"\r\n value={familyName}\r\n onChange={(e) => setFamilyName(e.target.value)}\r\n placeholder=\"e.g. Acme Sans\"\r\n className=\"w-full px-2.5 py-1.5 text-sm rounded-md border border-border bg-transparent focus:outline-none focus:ring-1 focus:ring-ring\"\r\n list=\"existing-families\"\r\n />\r\n {existingFamilies.length > 0 && (\r\n <datalist id=\"existing-families\">\r\n {existingFamilies.map((f) => (\r\n <option key={f} value={f} />\r\n ))}\r\n </datalist>\r\n )}\r\n {existingFamilies.includes(familyName.trim()) && (\r\n <p className=\"text-[11px] text-muted-foreground\">\r\n Will add as a new style to existing family \"{familyName.trim()}\"\r\n </p>\r\n )}\r\n </div>\r\n\r\n {/* Weight + Italic row */}\r\n <div className=\"flex gap-2 items-end\">\r\n <div className=\"flex-1 space-y-1\">\r\n <label className=\"text-xs text-muted-foreground\">Weight</label>\r\n <select\r\n value={weight}\r\n onChange={(e) => setWeight(Number(e.target.value) as FontWeight)}\r\n className=\"w-full px-2.5 py-1.5 text-sm rounded-md border border-border bg-transparent focus:outline-none focus:ring-1 focus:ring-ring\"\r\n >\r\n {WEIGHT_OPTIONS.map((w) => (\r\n <option key={w.value} value={w.value}>\r\n {w.label}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n <button\r\n onClick={() => setItalic(!italic)}\r\n className={cn(\r\n 'px-3 py-1.5 text-sm rounded-md border transition-colors shrink-0',\r\n italic\r\n ? 'border-primary bg-primary/10 text-primary font-medium italic'\r\n : 'border-border text-muted-foreground hover:border-muted-foreground',\r\n )}\r\n >\r\n Italic\r\n </button>\r\n </div>\r\n\r\n {/* File info */}\r\n <p className=\"text-[11px] text-muted-foreground truncate\">\r\n File: {style.fileName || 'unknown'}\r\n </p>\r\n\r\n {/* Actions */}\r\n <div className=\"flex gap-2 justify-end pt-1\">\r\n <button\r\n onClick={onCancel}\r\n className=\"px-3 py-1.5 text-xs font-medium rounded-md text-muted-foreground hover:bg-accent transition-colors\"\r\n >\r\n Cancel\r\n </button>\r\n <button\r\n onClick={handleConfirm}\r\n disabled={!familyName.trim()}\r\n className=\"px-3 py-1.5 text-xs font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-40 transition-colors\"\r\n >\r\n Add Font\r\n </button>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Existing custom font family card (collapsible, shows styles, delete)\r\n// ---------------------------------------------------------------------------\r\ninterface FontFamilyCardProps {\r\n family: CustomFontFamily;\r\n familyIndex: number;\r\n onDeleteFamily: (index: number) => void;\r\n onDeleteStyle: (familyIndex: number, styleIndex: number) => void;\r\n className?: string;\r\n}\r\n\r\nconst weightLabel = (w: FontWeight): string =>\r\n WEIGHT_OPTIONS.find((o) => o.value === w)?.label || `${w}`;\r\n\r\nexport const FontFamilyCard: React.FC<FontFamilyCardProps> = ({\r\n family,\r\n familyIndex,\r\n onDeleteFamily,\r\n onDeleteStyle,\r\n className,\r\n}) => {\r\n const [expanded, setExpanded] = useState(false);\r\n\r\n return (\r\n <div className={cn('rounded-lg border border-border bg-card', className)}>\r\n <button\r\n onClick={() => setExpanded(!expanded)}\r\n className=\"w-full flex items-center gap-2 px-3 py-2.5 text-left\"\r\n >\r\n <div className=\"flex-1 min-w-0\">\r\n <span className=\"text-sm font-medium text-foreground truncate block\">{family.name}</span>\r\n <span className=\"text-[11px] text-muted-foreground\">\r\n {family.fonts.length} style{family.fonts.length !== 1 ? 's' : ''}\r\n </span>\r\n </div>\r\n {expanded ? (\r\n <ChevronUp className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\r\n ) : (\r\n <ChevronDown className=\"w-3.5 h-3.5 text-muted-foreground shrink-0\" />\r\n )}\r\n </button>\r\n\r\n {expanded && (\r\n <div className=\"border-t border-border px-3 py-2 space-y-1.5\">\r\n {family.fonts.map((style, idx) => (\r\n <div\r\n key={idx}\r\n className=\"flex items-center gap-2 text-xs text-muted-foreground\"\r\n >\r\n <span className=\"flex-1 truncate\">\r\n {weightLabel(style.weight)}{style.italic ? ', Italic' : ''}\r\n {style.fileName && (\r\n <span className=\"ml-1 opacity-50\">— {style.fileName}</span>\r\n )}\r\n </span>\r\n <button\r\n onClick={(e) => { e.stopPropagation(); onDeleteStyle(familyIndex, idx); }}\r\n className=\"p-1 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive transition-colors shrink-0\"\r\n title=\"Remove style\"\r\n >\r\n <Trash2 className=\"w-3 h-3\" />\r\n </button>\r\n </div>\r\n ))}\r\n <div className=\"pt-1 border-t border-border\">\r\n <button\r\n onClick={(e) => { e.stopPropagation(); onDeleteFamily(familyIndex); }}\r\n className=\"text-[11px] text-destructive hover:text-destructive/80 font-medium transition-colors\"\r\n >\r\n Delete entire family\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","// =============================================================================\r\n// FONT PICKER — Component\r\n// =============================================================================\r\n// Tabbed picker: Google Fonts catalog + Custom uploaded fonts.\r\n// Custom fonts are stored via appConfiguration config with full\r\n// weight/italic metadata per style. Upload auto-detects metadata\r\n// from filenames and lets users adjust before saving.\r\n// =============================================================================\r\n\r\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\r\nimport type { FontPickerProps, FontSelection, FontEntry, FontCategory, CustomFontStyle } from './types';\r\nimport { useFontSearch, fontFamilyFromFilename } from './useFontSearch';\r\nimport { CATEGORY_FALLBACKS } from './google-fonts';\r\nimport { cn } from '../../utils/cn';\r\nimport { Search, X, ChevronLeft, ChevronRight, Loader2, Type, Upload, Check } from 'lucide-react';\r\nimport { FontUploadZone } from './FontUploadZone';\r\nimport { FontUploadForm, FontFamilyCard } from './FontStyleEditor';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Font preview loader — injects a <link> to load font for preview\r\n// ---------------------------------------------------------------------------\r\nconst loadedFonts = new Set<string>();\r\n\r\nfunction ensureFontLoaded(entry: FontEntry) {\r\n if (!entry.loadUrl || loadedFonts.has(entry.family)) return;\r\n loadedFonts.add(entry.family);\r\n\r\n if (entry.source === 'google') {\r\n const link = document.createElement('link');\r\n link.rel = 'stylesheet';\r\n link.href = entry.loadUrl;\r\n link.dataset.fontPicker = entry.family;\r\n document.head.appendChild(link);\r\n } else if (entry.source === 'custom') {\r\n const style = document.createElement('style');\r\n style.dataset.fontPicker = entry.family;\r\n style.textContent = `@font-face { font-family: '${entry.family}'; src: url('${entry.loadUrl}'); font-display: swap; }`;\r\n document.head.appendChild(style);\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Build selection result\r\n// ---------------------------------------------------------------------------\r\nfunction buildSelection(entry: FontEntry): FontSelection {\r\n const fallback = CATEGORY_FALLBACKS[entry.category || 'sans-serif'];\r\n const cssFontFamily = `'${entry.family}', ${fallback}`;\r\n\r\n let loadSnippet: string;\r\n if (entry.source === 'google' && entry.loadUrl) {\r\n loadSnippet = `<link href=\"${entry.loadUrl}\" rel=\"stylesheet\">`;\r\n } else if (entry.source === 'custom' && entry.loadUrl) {\r\n loadSnippet = `@font-face {\\n font-family: '${entry.family}';\\n src: url('${entry.loadUrl}');\\n font-display: swap;\\n}`;\r\n } else {\r\n loadSnippet = `/* Font \"${entry.family}\" — no load URL available */`;\r\n }\r\n\r\n return {\r\n family: entry.family,\r\n source: entry.source,\r\n loadUrl: entry.loadUrl,\r\n category: entry.category,\r\n weights: entry.weights,\r\n fileUrl: entry.source === 'custom' ? entry.loadUrl : undefined,\r\n assetId: entry.assetId,\r\n cssFontFamily,\r\n loadSnippet,\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Font Item Row\r\n// ---------------------------------------------------------------------------\r\nconst FontItem: React.FC<{\r\n entry: FontEntry;\r\n isSelected: boolean;\r\n previewText: string;\r\n showPreview: boolean;\r\n onClick: () => void;\r\n}> = ({ entry, isSelected, previewText, showPreview, onClick }) => {\r\n const ref = useRef<HTMLButtonElement>(null);\r\n\r\n useEffect(() => {\r\n if (!ref.current) return;\r\n const observer = new IntersectionObserver(\r\n ([e]) => { if (e.isIntersecting) { ensureFontLoaded(entry); observer.disconnect(); } },\r\n { rootMargin: '100px' },\r\n );\r\n observer.observe(ref.current);\r\n return () => observer.disconnect();\r\n }, [entry]);\r\n\r\n return (\r\n <button\r\n ref={ref}\r\n onClick={onClick}\r\n className={cn(\r\n 'w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-left transition-colors',\r\n isSelected\r\n ? 'bg-primary/10 ring-1 ring-primary'\r\n : 'hover:bg-accent/50',\r\n )}\r\n >\r\n <div className=\"flex-1 min-w-0\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-sm font-medium text-foreground truncate\">\r\n {entry.family}\r\n </span>\r\n {entry.source === 'custom' && (\r\n <span className=\"shrink-0 inline-flex items-center gap-1 px-1.5 py-0.5 text-[10px] font-medium rounded bg-accent text-accent-foreground\">\r\n <Upload className=\"w-2.5 h-2.5\" />\r\n Custom\r\n </span>\r\n )}\r\n {entry.source === 'custom' && entry.weights && entry.weights.length > 0 && (\r\n <span className=\"shrink-0 text-[10px] text-muted-foreground\">\r\n {entry.weights.length} style{entry.weights.length !== 1 ? 's' : ''}\r\n </span>\r\n )}\r\n {entry.category && entry.source === 'google' && (\r\n <span className=\"shrink-0 text-[10px] text-muted-foreground capitalize\">\r\n {entry.category}\r\n </span>\r\n )}\r\n </div>\r\n {showPreview && (\r\n <p\r\n className=\"text-base text-muted-foreground mt-0.5 truncate\"\r\n style={{ fontFamily: `'${entry.family}', sans-serif` }}\r\n >\r\n {previewText}\r\n </p>\r\n )}\r\n </div>\r\n {isSelected && (\r\n <Check className=\"w-4 h-4 text-primary shrink-0\" />\r\n )}\r\n </button>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Font Picker Content\r\n// ---------------------------------------------------------------------------\r\nconst FontPickerContent: React.FC<\r\n FontPickerProps & { onConfirm?: (font: FontSelection) => void }\r\n> = ({\r\n value,\r\n onSelect,\r\n onConfirm,\r\n scope,\r\n fontsConfigAppId,\r\n showCustomFonts = false,\r\n categories,\r\n showPreview = true,\r\n previewText = 'The quick brown fox jumps over the lazy dog',\r\n pageSize = 50,\r\n admin,\r\n className,\r\n}) => {\r\n const {\r\n loading,\r\n setSearch,\r\n activeTab,\r\n setActiveTab,\r\n hasCustomFonts,\r\n customFontCount,\r\n customFamilies,\r\n activeCategory,\r\n setActiveCategory,\r\n availableCategories,\r\n pageFonts,\r\n page,\r\n setPage,\r\n totalPages,\r\n totalCount,\r\n categoryLabels,\r\n uploading,\r\n uploadProgress,\r\n uploadFont,\r\n addFontStyle,\r\n deleteFontFamily,\r\n deleteFontStyle,\r\n } = useFontSearch({ categories, scope, showCustomFonts, admin, pageSize, fontsConfigAppId });\r\n\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n useEffect(() => { inputRef.current?.focus(); }, []);\r\n\r\n // Post-upload form state\r\n const [pendingStyle, setPendingStyle] = useState<CustomFontStyle | null>(null);\r\n const [pendingFamilyName, setPendingFamilyName] = useState('');\r\n\r\n const handleUpload = useCallback(async (file: File) => {\r\n const style = await uploadFont(file);\r\n if (style) {\r\n setPendingFamilyName(fontFamilyFromFilename(file.name));\r\n setPendingStyle(style);\r\n }\r\n return style;\r\n }, [uploadFont]);\r\n\r\n const handleConfirmUpload = useCallback(async (familyName: string, style: CustomFontStyle) => {\r\n await addFontStyle(familyName, style);\r\n setPendingStyle(null);\r\n setPendingFamilyName('');\r\n }, [addFontStyle]);\r\n\r\n const handleSelect = useCallback(\r\n (entry: FontEntry) => {\r\n const selection = buildSelection(entry);\r\n onSelect?.(selection);\r\n onConfirm?.(selection);\r\n },\r\n [onSelect, onConfirm],\r\n );\r\n\r\n return (\r\n <div className={cn('space-y-3', className)}>\r\n {/* Search */}\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\r\n <input\r\n ref={inputRef}\r\n type=\"text\"\r\n placeholder=\"Search fonts…\"\r\n onChange={(e) => setSearch(e.target.value)}\r\n className=\"w-full pl-9 pr-3 py-2 text-sm rounded-md border border-border bg-transparent focus:outline-none focus:ring-1 focus:ring-ring\"\r\n />\r\n </div>\r\n\r\n {/* Tabs: Google / Custom */}\r\n {hasCustomFonts && (\r\n <div className=\"flex gap-1 border-b border-border pb-2\">\r\n <button\r\n onClick={() => setActiveTab('google')}\r\n className={cn(\r\n 'px-3 py-1.5 text-xs font-semibold rounded-md transition-colors inline-flex items-center gap-1.5',\r\n activeTab === 'google'\r\n ? 'bg-primary text-primary-foreground'\r\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\r\n )}\r\n >\r\n <Type className=\"w-3.5 h-3.5\" />\r\n Google Fonts\r\n </button>\r\n <button\r\n onClick={() => setActiveTab('custom')}\r\n className={cn(\r\n 'px-3 py-1.5 text-xs font-semibold rounded-md transition-colors inline-flex items-center gap-1.5',\r\n activeTab === 'custom'\r\n ? 'bg-primary text-primary-foreground'\r\n : 'text-muted-foreground hover:bg-accent hover:text-accent-foreground',\r\n )}\r\n >\r\n <Upload className=\"w-3.5 h-3.5\" />\r\n Custom\r\n {customFontCount > 0 && (\r\n <span className=\"ml-1 text-[10px] opacity-70\">({customFontCount})</span>\r\n )}\r\n </button>\r\n </div>\r\n )}\r\n\r\n {/* Category pills (Google tab only) */}\r\n {activeTab === 'google' && availableCategories.length > 1 && (\r\n <div className=\"flex gap-1 flex-wrap items-center\">\r\n <button\r\n onClick={() => setActiveCategory(null)}\r\n className={cn(\r\n 'px-2.5 py-1 text-xs font-medium rounded-full transition-colors',\r\n !activeCategory\r\n ? 'bg-foreground text-background'\r\n : 'bg-muted text-muted-foreground hover:bg-accent',\r\n )}\r\n >\r\n All\r\n </button>\r\n {availableCategories.map((c) => (\r\n <button\r\n key={c}\r\n onClick={() => setActiveCategory(c === activeCategory ? null : c)}\r\n className={cn(\r\n 'px-2.5 py-1 text-xs font-medium rounded-full transition-colors',\r\n c === activeCategory\r\n ? 'bg-foreground text-background'\r\n : 'bg-muted text-muted-foreground hover:bg-accent',\r\n )}\r\n >\r\n {categoryLabels[c]}\r\n </button>\r\n ))}\r\n <span className=\"ml-auto text-[11px] text-muted-foreground\">{totalCount} fonts</span>\r\n </div>\r\n )}\r\n\r\n {/* Custom tab content */}\r\n {activeTab === 'custom' && !loading && (\r\n <div className=\"space-y-3\">\r\n {/* Upload zone */}\r\n {scope?.collectionId && (\r\n <FontUploadZone\r\n uploading={uploading}\r\n uploadProgress={uploadProgress}\r\n onUpload={handleUpload}\r\n />\r\n )}\r\n\r\n {/* Post-upload metadata form */}\r\n {pendingStyle && (\r\n <FontUploadForm\r\n defaultFamilyName={pendingFamilyName}\r\n style={pendingStyle}\r\n existingFamilies={customFamilies.map((f) => f.name)}\r\n onConfirm={handleConfirmUpload}\r\n onCancel={() => { setPendingStyle(null); setPendingFamilyName(''); }}\r\n />\r\n )}\r\n\r\n {/* Existing custom font families */}\r\n {customFamilies.length > 0 && (\r\n <div className=\"space-y-2\">\r\n <p className=\"text-[11px] font-medium text-muted-foreground uppercase tracking-wide\">\r\n Uploaded Fonts ({customFamilies.length})\r\n </p>\r\n {customFamilies.map((fam, idx) => (\r\n <FontFamilyCard\r\n key={`${fam.name}-${idx}`}\r\n family={fam}\r\n familyIndex={idx}\r\n onDeleteFamily={deleteFontFamily}\r\n onDeleteStyle={deleteFontStyle}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Loading state for custom fonts */}\r\n {loading && activeTab === 'custom' && (\r\n <div className=\"flex flex-col items-center justify-center py-12 gap-3\">\r\n <Loader2 className=\"w-6 h-6 animate-spin text-muted-foreground\" />\r\n <p className=\"text-sm text-muted-foreground\">Loading custom fonts…</p>\r\n </div>\r\n )}\r\n\r\n {/* Font list (Google tab or custom tab font selection) */}\r\n {activeTab === 'google' && (\r\n <>\r\n {!loading && pageFonts.length === 0 ? (\r\n <div className=\"flex flex-col items-center justify-center py-10 gap-2\">\r\n <Type className=\"w-6 h-6 text-muted-foreground/40\" />\r\n <p className=\"text-sm text-muted-foreground\">No fonts found</p>\r\n </div>\r\n ) : (\r\n !loading && (\r\n <div className=\"space-y-0.5 max-h-[400px] overflow-y-auto\">\r\n {pageFonts.map((font) => (\r\n <FontItem\r\n key={`${font.source}-${font.family}`}\r\n entry={font}\r\n isSelected={value === font.family}\r\n previewText={previewText}\r\n showPreview={showPreview}\r\n onClick={() => handleSelect(font)}\r\n />\r\n ))}\r\n </div>\r\n )\r\n )}\r\n\r\n {/* Pagination */}\r\n {totalPages > 1 && (\r\n <div className=\"flex items-center justify-center gap-2\">\r\n <button\r\n onClick={() => setPage(Math.max(0, page - 1))}\r\n disabled={page === 0}\r\n className=\"p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors\"\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {page + 1} / {totalPages}\r\n </span>\r\n <button\r\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\r\n disabled={page >= totalPages - 1}\r\n className=\"p-1 rounded hover:bg-accent disabled:opacity-30 transition-colors\"\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n )}\r\n </>\r\n )}\r\n\r\n {/* Custom tab: selectable font list (below the management cards) */}\r\n {activeTab === 'custom' && !loading && pageFonts.length > 0 && (\r\n <>\r\n <div className=\"space-y-0.5 max-h-[300px] overflow-y-auto border-t border-border pt-3\">\r\n <p className=\"text-[11px] font-medium text-muted-foreground uppercase tracking-wide mb-2\">\r\n Select a Custom Font\r\n </p>\r\n {pageFonts.map((font) => (\r\n <FontItem\r\n key={`${font.source}-${font.family}`}\r\n entry={font}\r\n isSelected={value === font.family}\r\n previewText={previewText}\r\n showPreview={showPreview}\r\n onClick={() => handleSelect(font)}\r\n />\r\n ))}\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Dialog wrapper\r\n// ---------------------------------------------------------------------------\r\nconst PickerDialog: React.FC<{\r\n open: boolean;\r\n onClose: () => void;\r\n children: React.ReactNode;\r\n}> = ({ open, onClose, children }) => {\r\n if (!open) return null;\r\n return (\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\r\n <div className=\"absolute inset-0 bg-black/50 backdrop-blur-sm\" onClick={onClose} />\r\n <div className=\"relative z-10 w-full max-w-lg max-h-[80vh] bg-background rounded-xl shadow-2xl border border-border flex flex-col overflow-hidden mx-4\">\r\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-border\">\r\n <h3 className=\"text-sm font-semibold text-foreground\">Select Font</h3>\r\n <button onClick={onClose} className=\"p-1 rounded hover:bg-accent transition-colors\">\r\n <X className=\"w-4 h-4 text-muted-foreground\" />\r\n </button>\r\n </div>\r\n <div className=\"flex-1 overflow-y-auto p-4\">{children}</div>\r\n </div>\r\n </div>\r\n );\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Public API\r\n// ---------------------------------------------------------------------------\r\nexport const FontPicker: React.FC<FontPickerProps> = (props) => {\r\n const {\r\n mode = 'inline',\r\n trigger,\r\n open: controlledOpen,\r\n onClose,\r\n value,\r\n onSelect,\r\n className,\r\n ...rest\r\n } = props;\r\n\r\n const [internalOpen, setInternalOpen] = useState(false);\r\n const isOpen = controlledOpen ?? internalOpen;\r\n\r\n const handleClose = useCallback(() => {\r\n setInternalOpen(false);\r\n onClose?.();\r\n }, [onClose]);\r\n\r\n const handleSelectAndClose = useCallback(\r\n (font: FontSelection) => {\r\n onSelect?.(font);\r\n handleClose();\r\n },\r\n [onSelect, handleClose],\r\n );\r\n\r\n if (mode === 'inline') {\r\n return <FontPickerContent value={value} onSelect={onSelect} className={className} {...rest} />;\r\n }\r\n\r\n const triggerElement = trigger || (\r\n <div\r\n className={cn(\r\n 'inline-flex items-center gap-2 px-3 py-2 rounded-md border border-border cursor-pointer',\r\n 'hover:border-ring transition-colors',\r\n className,\r\n )}\r\n >\r\n {value ? (\r\n <span className=\"text-sm text-foreground\" style={{ fontFamily: `'${value}', sans-serif` }}>\r\n {value}\r\n </span>\r\n ) : (\r\n <span className=\"text-sm text-muted-foreground\">Choose font…</span>\r\n )}\r\n <Type className=\"w-3.5 h-3.5 text-muted-foreground ml-auto\" />\r\n </div>\r\n );\r\n\r\n return (\r\n <>\r\n <span onClick={() => setInternalOpen(true)} className=\"cursor-pointer\">\r\n {triggerElement}\r\n </span>\r\n <PickerDialog open={isOpen} onClose={handleClose}>\r\n <FontPickerContent value={value} onSelect={handleSelectAndClose} {...rest} />\r\n </PickerDialog>\r\n </>\r\n );\r\n};\r\n"]}
|