@commercetools-demo/puck-image-picker 0.4.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/ImagePickerField.tsx","../src/hooks/useMediaLibrary.ts","../src/api/media-library.api.ts","../src/context/ImagePickerContext.tsx","../src/context/ImagePickerProvider.tsx"],"sourcesContent":["export { ImagePickerField } from './ImagePickerField';\nexport type { ImagePickerFieldProps } from './ImagePickerField';\n\nexport { ImagePickerProvider } from './context/ImagePickerProvider';\nexport type { ImagePickerProviderProps } from './context/ImagePickerProvider';\nexport type { ImagePickerConfig } from './context/ImagePickerContext';\n\nexport { useMediaLibrary } from './hooks/useMediaLibrary';\nexport type { UseMediaLibraryReturn } from './hooks/useMediaLibrary';\n\nexport type { MediaFile, MediaLibraryPagination, MediaLibraryResult } from './types';\n","import React, {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useMediaLibrary } from './hooks/useMediaLibrary';\nimport type { MediaFile } from './types';\nimport PrimaryButton from '@commercetools-uikit/primary-button';\nimport SecondaryButton from '@commercetools-uikit/secondary-button';\nimport FlatButton from '@commercetools-uikit/flat-button';\nimport SecondaryIconButton from '@commercetools-uikit/secondary-icon-button';\nimport TextInput from '@commercetools-uikit/text-input';\nimport Label from '@commercetools-uikit/label';\nimport LoadingSpinner from '@commercetools-uikit/loading-spinner';\nimport Spacings from '@commercetools-uikit/spacings';\nimport Text from '@commercetools-uikit/text';\nimport { CloseIcon } from '@commercetools-uikit/icons';\n\n// ---------------------------------------------------------------------------\n// Upload modal\n// ---------------------------------------------------------------------------\n\ninterface UploadModalProps {\n uploading: boolean;\n error: string | null;\n imagesOnly: boolean;\n onUpload: (file: File, title: string, description: string) => void;\n onClose: () => void;\n}\n\nconst UploadModal: React.FC<UploadModalProps> = ({\n uploading,\n error,\n imagesOnly,\n onUpload,\n onClose,\n}) => {\n const [file, setFile] = useState<File | null>(null);\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleFile = (f: File) => {\n setFile(f);\n if (!title) setTitle(f.name);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = e.dataTransfer.files[0];\n if (f) handleFile(f);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text.Subheadline as=\"h4\" isBold>Upload a file</Text.Subheadline>\n <SecondaryIconButton\n icon={<CloseIcon />}\n label=\"Close\"\n onClick={onClose}\n size=\"small\"\n />\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n <Spacings.Stack scale=\"m\">\n <Spacings.Stack scale=\"xs\">\n <Label htmlFor=\"upload-title\">Title</Label>\n <TextInput\n id=\"upload-title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"File title\"\n />\n </Spacings.Stack>\n <Spacings.Stack scale=\"xs\">\n <Label htmlFor=\"upload-description\">Description</Label>\n <TextInput\n id=\"upload-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder=\"Optional description\"\n />\n </Spacings.Stack>\n <div\n style={{\n border: dragging ? '2px dashed #3b82f6' : '2px dashed #d1d5db',\n borderRadius: '6px',\n padding: '24px',\n textAlign: 'center',\n cursor: 'pointer',\n color: dragging ? '#3b82f6' : '#6b7280',\n fontSize: '13px',\n transition: 'border-color .2s',\n }}\n onClick={() => inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onDrop={handleDrop}\n >\n {file ? (\n <>\n <div>📎 {file.name}</div>\n <div style={{ fontSize: '11px', marginTop: '4px', color: '#9ca3af' }}>\n {(file.size / 1024).toFixed(0)} KB\n </div>\n </>\n ) : (\n <div>📁 Click or drag &amp; drop to select a file</div>\n )}\n <input\n ref={inputRef}\n type=\"file\"\n accept={imagesOnly ? 'image/*' : '*/*'}\n style={{ display: 'none' }}\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) handleFile(f);\n }}\n />\n </div>\n {error && <Text.Body tone=\"negative\">{error}</Text.Body>}\n </Spacings.Stack>\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text.Detail tone=\"secondary\" truncate>\n {file?.name ?? 'No file selected'}\n </Text.Detail>\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Cancel\" onClick={onClose} />\n <PrimaryButton\n label={uploading ? 'Uploading…' : 'Upload'}\n isDisabled={!file || uploading}\n onClick={() => file && onUpload(file, title, description)}\n />\n </Spacings.Inline>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Library modal\n// ---------------------------------------------------------------------------\n\ninterface LibraryModalProps {\n files: MediaFile[];\n pagination: { currentPage: number; totalPages: number };\n loading: boolean;\n error: string | null;\n onNextPage: () => void;\n onPrevPage: () => void;\n onSelect: (file: MediaFile) => void;\n onClose: () => void;\n}\n\nconst LibraryModal: React.FC<LibraryModalProps> = ({\n files,\n pagination,\n loading,\n error,\n onNextPage,\n onPrevPage,\n onSelect,\n onClose,\n}) => {\n const [selected, setSelected] = useState<MediaFile | null>(null);\n\n const handleConfirm = () => {\n if (selected) onSelect(selected);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text.Subheadline as=\"h4\" isBold>Select from Media Library</Text.Subheadline>\n <SecondaryIconButton\n icon={<CloseIcon />}\n label=\"Close\"\n onClick={onClose}\n size=\"small\"\n />\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n {loading ? (\n <div style={{ display: 'flex', justifyContent: 'center', padding: '32px' }}>\n <LoadingSpinner />\n </div>\n ) : files.length === 0 ? (\n <Text.Body tone=\"secondary\">No files found.</Text.Body>\n ) : (\n <Spacings.Stack scale=\"m\">\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(110px, 1fr))',\n gap: '12px',\n }}\n >\n {files.map((file) => (\n <div\n key={file.url}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n border: `2px solid ${selected?.url === file.url ? '#3b82f6' : 'transparent'}`,\n borderRadius: '6px',\n padding: '6px',\n background: selected?.url === file.url ? 'rgba(59,130,246,0.07)' : '#f9fafb',\n }}\n onClick={() => setSelected(file)}\n title={file.title ?? file.name}\n >\n {file.isImage ? (\n <img\n src={file.url}\n alt={file.name}\n style={{ width: '80px', height: '80px', objectFit: 'cover', borderRadius: '4px', background: '#e5e7eb' }}\n />\n ) : (\n <div\n style={{\n width: '80px',\n height: '80px',\n borderRadius: '4px',\n background: '#e5e7eb',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '28px',\n }}\n >\n 📄\n </div>\n )}\n <div\n style={{\n marginTop: '6px',\n fontSize: '11px',\n textAlign: 'center',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: '#374151',\n }}\n >\n {file.title ?? file.name}\n </div>\n </div>\n ))}\n </div>\n\n {pagination.totalPages > 1 && (\n <Spacings.Inline alignItems=\"center\" justifyContent=\"center\" scale=\"s\">\n <SecondaryButton\n label=\"← Prev\"\n isDisabled={pagination.currentPage <= 1}\n onClick={onPrevPage}\n size=\"small\"\n />\n <Text.Detail tone=\"secondary\">\n {pagination.currentPage} / {pagination.totalPages}\n </Text.Detail>\n <SecondaryButton\n label=\"Next →\"\n isDisabled={pagination.currentPage >= pagination.totalPages}\n onClick={onNextPage}\n size=\"small\"\n />\n </Spacings.Inline>\n )}\n </Spacings.Stack>\n )}\n {error && <Text.Body tone=\"negative\">{error}</Text.Body>}\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text.Detail tone=\"secondary\" truncate>\n {selected ? (selected.title ?? selected.name) : 'Nothing selected'}\n </Text.Detail>\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Cancel\" onClick={onClose} />\n <PrimaryButton\n label=\"Select\"\n isDisabled={!selected}\n onClick={handleConfirm}\n />\n </Spacings.Inline>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// ImagePickerField — standalone field component\n// ---------------------------------------------------------------------------\n\nexport interface ImagePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n /** Only show images (default: true) */\n imagesOnly?: boolean;\n}\n\nexport const ImagePickerField: React.FC<ImagePickerFieldProps> = ({\n value,\n onChange,\n imagesOnly = true,\n}) => {\n const {\n files,\n pagination,\n loading,\n uploading,\n error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n } = useMediaLibrary();\n\n const [showUpload, setShowUpload] = useState(false);\n const [showLibrary, setShowLibrary] = useState(false);\n\n const extensions = imagesOnly ? ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'] : [];\n\n const openLibrary = useCallback(() => {\n void fetchMedia(extensions, 1, 20);\n setShowLibrary(true);\n }, [fetchMedia, extensions]);\n\n const handleUpload = useCallback(\n async (file: File, title: string, description: string) => {\n const mediaFile = await uploadFile(file, title, description);\n onChange(mediaFile.url);\n setShowUpload(false);\n },\n [uploadFile, onChange]\n );\n\n const handleSelect = useCallback(\n (file: MediaFile) => {\n onChange(file.url);\n setShowLibrary(false);\n },\n [onChange]\n );\n\n // Close modals on Escape\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setShowUpload(false);\n setShowLibrary(false);\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return (\n <Spacings.Stack scale=\"s\">\n {value ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '8px',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n background: '#f9fafb',\n }}\n >\n <img\n src={value}\n alt=\"\"\n style={{ width: '48px', height: '48px', objectFit: 'cover', borderRadius: '4px', flexShrink: 0 }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <Text.Detail tone=\"secondary\" truncate>{value}</Text.Detail>\n </div>\n <FlatButton tone=\"critical\" label=\"Remove\" onClick={() => onChange('')} />\n </div>\n ) : (\n <Text.Detail tone=\"secondary\">No image selected</Text.Detail>\n )}\n\n <Spacings.Inline scale=\"s\">\n <SecondaryButton label=\"Upload\" onClick={() => setShowUpload(true)} />\n <PrimaryButton label=\"Media Library\" onClick={openLibrary} />\n </Spacings.Inline>\n\n {showUpload && (\n <UploadModal\n uploading={uploading}\n error={error}\n imagesOnly={imagesOnly}\n onUpload={(file, title, desc) => void handleUpload(file, title, desc)}\n onClose={() => setShowUpload(false)}\n />\n )}\n\n {showLibrary && (\n <LibraryModal\n files={files}\n pagination={pagination}\n loading={loading}\n error={error}\n onNextPage={() => void loadNextPage(extensions)}\n onPrevPage={() => void loadPreviousPage(extensions)}\n onSelect={handleSelect}\n onClose={() => setShowLibrary(false)}\n />\n )}\n </Spacings.Stack>\n );\n};\n","import { useCallback, useState } from 'react';\nimport type {\n MediaFile,\n MediaLibraryPagination,\n} from '../types';\nimport {\n fetchMediaLibraryApi,\n uploadMediaFileApi,\n} from '../api/media-library.api';\nimport { useImagePickerContext } from '../context/ImagePickerContext';\n\ninterface MediaLibraryState {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n}\n\nconst initialPagination: MediaLibraryPagination = {\n totalItems: 0,\n totalPages: 0,\n currentPage: 1,\n limit: 20,\n};\n\nexport interface UseMediaLibraryReturn {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n fetchMedia: (\n extensions?: string[],\n page?: number,\n limit?: number\n ) => Promise<void>;\n uploadFile: (\n file: File,\n title?: string,\n description?: string\n ) => Promise<MediaFile>;\n loadNextPage: (extensions?: string[]) => Promise<void>;\n loadPreviousPage: (extensions?: string[]) => Promise<void>;\n hasNextPage: () => boolean;\n hasPreviousPage: () => boolean;\n}\n\nexport const useMediaLibrary = (): UseMediaLibraryReturn => {\n const { baseURL, projectKey, businessUnitKey, jwtToken } =\n useImagePickerContext();\n\n const [state, setState] = useState<MediaLibraryState>({\n files: [],\n pagination: initialPagination,\n loading: false,\n uploading: false,\n error: null,\n });\n\n const fetchMedia = useCallback(\n async (\n extensions: string[] = [],\n page = 1,\n limit = 20\n ): Promise<void> => {\n setState((s) => ({ ...s, loading: true, error: null }));\n try {\n const result = await fetchMediaLibraryApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n extensions,\n page,\n limit\n );\n setState((s) => ({\n ...s,\n files: result.files,\n pagination: result.pagination,\n loading: false,\n }));\n } catch (err) {\n setState((s) => ({\n ...s,\n loading: false,\n error: (err as Error).message,\n }));\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const uploadFile = useCallback(\n async (\n file: File,\n title?: string,\n description?: string\n ): Promise<MediaFile> => {\n if (!jwtToken) throw new Error('jwtToken is required to upload files');\n setState((s) => ({ ...s, uploading: true, error: null }));\n try {\n const result = await uploadMediaFileApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n file,\n title,\n description\n );\n const mediaFile: MediaFile = {\n url: result.url,\n name: file.name,\n title: title ?? file.name,\n description,\n isImage: file.type.startsWith('image/'),\n createdAt: new Date().toISOString(),\n size: file.size,\n };\n setState((s) => ({\n ...s,\n files: [mediaFile, ...s.files],\n pagination: {\n ...s.pagination,\n totalItems: s.pagination.totalItems + 1,\n },\n uploading: false,\n }));\n return mediaFile;\n } catch (err) {\n setState((s) => ({\n ...s,\n uploading: false,\n error: (err as Error).message,\n }));\n throw err;\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const loadNextPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const next = state.pagination.currentPage + 1;\n if (next <= state.pagination.totalPages) {\n await fetchMedia(extensions, next, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const loadPreviousPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const prev = state.pagination.currentPage - 1;\n if (prev >= 1) {\n await fetchMedia(extensions, prev, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const hasNextPage = useCallback(\n () => state.pagination.currentPage < state.pagination.totalPages,\n [state.pagination]\n );\n\n const hasPreviousPage = useCallback(\n () => state.pagination.currentPage > 1,\n [state.pagination]\n );\n\n return {\n files: state.files,\n pagination: state.pagination,\n loading: state.loading,\n uploading: state.uploading,\n error: state.error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n hasNextPage,\n hasPreviousPage,\n };\n};\n","import type { MediaLibraryResult } from '../types';\n\n/**\n * Fetch media library files for a business unit.\n * Maps to GET /service/:businessUnitKey/media-library\n */\nexport const fetchMediaLibraryApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken?: string,\n extensions: string[] = [],\n page = 1,\n limit = 20\n): Promise<MediaLibraryResult> => {\n const params = new URLSearchParams();\n if (extensions.length > 0) params.set('extensions', extensions.join(','));\n params.set('page', String(page));\n params.set('limit', String(limit));\n\n const headers: Record<string, string> = {\n 'x-project-key': projectKey,\n };\n if (jwtToken) headers['Authorization'] = `Bearer ${jwtToken}`;\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/media-library?${params}`,\n { headers }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<MediaLibraryResult>;\n};\n\n/**\n * Upload a file for a business unit.\n * Maps to POST /service/:businessUnitKey/upload-file\n */\nexport const uploadMediaFileApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken: string,\n file: File,\n title?: string,\n description?: string\n): Promise<{ url: string }> => {\n const formData = new FormData();\n formData.append('file', file);\n if (title) formData.append('title', title);\n if (description) formData.append('description', description);\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/upload-file`,\n {\n method: 'POST',\n headers: {\n 'x-project-key': projectKey,\n Authorization: `Bearer ${jwtToken}`,\n },\n body: formData,\n }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<{ url: string }>;\n};\n","import { createContext, useContext } from 'react';\n\nexport interface ImagePickerConfig {\n baseURL: string;\n projectKey: string;\n businessUnitKey: string;\n jwtToken?: string;\n}\n\nexport const ImagePickerContext = createContext<ImagePickerConfig | null>(null);\n\nexport const useImagePickerContext = (): ImagePickerConfig => {\n const ctx = useContext(ImagePickerContext);\n if (!ctx) {\n throw new Error(\n 'useImagePickerContext must be used inside <ImagePickerProvider>. ' +\n 'Wrap your component tree with <ImagePickerProvider>.'\n );\n }\n return ctx;\n};\n","import React, { type ReactNode } from 'react';\nimport { ImagePickerContext, type ImagePickerConfig } from './ImagePickerContext';\n\nexport interface ImagePickerProviderProps extends ImagePickerConfig {\n children: ReactNode;\n}\n\nexport const ImagePickerProvider: React.FC<ImagePickerProviderProps> = ({\n children,\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n}) => {\n return (\n <ImagePickerContext.Provider\n value={{ baseURL, projectKey, businessUnitKey, jwtToken }}\n >\n {children}\n </ImagePickerContext.Provider>\n );\n};\n"],"mappings":"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","names":["import_react","import_react","Text","SecondaryIconButton","Spacings","Label","TextInput","SecondaryButton","PrimaryButton","LoadingSpinner","FlatButton","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/ImagePickerField.tsx","../src/hooks/useMediaLibrary.ts","../src/api/media-library.api.ts","../src/context/ImagePickerContext.tsx","../src/EnsureNimbusProvider.tsx","../src/context/ImagePickerProvider.tsx"],"sourcesContent":["export { ImagePickerField } from './ImagePickerField';\nexport type { ImagePickerFieldProps } from './ImagePickerField';\n\nexport { ImagePickerProvider } from './context/ImagePickerProvider';\nexport type { ImagePickerProviderProps } from './context/ImagePickerProvider';\nexport type { ImagePickerConfig } from './context/ImagePickerContext';\n\nexport { useMediaLibrary } from './hooks/useMediaLibrary';\nexport type { UseMediaLibraryReturn } from './hooks/useMediaLibrary';\n\nexport type { MediaFile, MediaLibraryPagination, MediaLibraryResult } from './types';\n","import React, {\n useCallback,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { useMediaLibrary } from './hooks/useMediaLibrary';\nimport type { MediaFile } from './types';\nimport {\n Button,\n FormField,\n IconButton,\n LoadingSpinner,\n Stack,\n Text,\n TextInput,\n} from '@commercetools/nimbus';\nimport { Close } from '@commercetools/nimbus-icons';\nimport { EnsureNimbusProvider } from './EnsureNimbusProvider';\n\n// ---------------------------------------------------------------------------\n// Upload modal\n// ---------------------------------------------------------------------------\n\ninterface UploadModalProps {\n uploading: boolean;\n error: string | null;\n imagesOnly: boolean;\n onUpload: (file: File, title: string, description: string) => void;\n onClose: () => void;\n}\n\nconst UploadModal: React.FC<UploadModalProps> = ({\n uploading,\n error,\n imagesOnly,\n onUpload,\n onClose,\n}) => {\n const [file, setFile] = useState<File | null>(null);\n const [title, setTitle] = useState('');\n const [description, setDescription] = useState('');\n const [dragging, setDragging] = useState(false);\n const inputRef = useRef<HTMLInputElement>(null);\n\n const handleFile = (f: File) => {\n setFile(f);\n if (!title) setTitle(f.name);\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setDragging(false);\n const f = e.dataTransfer.files[0];\n if (f) handleFile(f);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text as=\"h4\" fontSize=\"xl\" fontWeight=\"700\">Upload a file</Text>\n <IconButton aria-label=\"Close\" variant=\"ghost\" size=\"xs\" onPress={onClose}>\n <Close />\n </IconButton>\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n <Stack direction=\"column\" gap=\"400\">\n <FormField.Root>\n <FormField.Label>Title</FormField.Label>\n <FormField.Input>\n <TextInput\n value={title}\n onChange={(value) => setTitle(value)}\n placeholder=\"File title\"\n />\n </FormField.Input>\n </FormField.Root>\n <FormField.Root>\n <FormField.Label>Description</FormField.Label>\n <FormField.Input>\n <TextInput\n value={description}\n onChange={(value) => setDescription(value)}\n placeholder=\"Optional description\"\n />\n </FormField.Input>\n </FormField.Root>\n <div\n style={{\n border: dragging ? '2px dashed #3b82f6' : '2px dashed #d1d5db',\n borderRadius: '6px',\n padding: '24px',\n textAlign: 'center',\n cursor: 'pointer',\n color: dragging ? '#3b82f6' : '#6b7280',\n fontSize: '13px',\n transition: 'border-color .2s',\n }}\n onClick={() => inputRef.current?.click()}\n onDragOver={(e) => { e.preventDefault(); setDragging(true); }}\n onDragLeave={() => setDragging(false)}\n onDrop={handleDrop}\n >\n {file ? (\n <>\n <div>📎 {file.name}</div>\n <div style={{ fontSize: '11px', marginTop: '4px', color: '#9ca3af' }}>\n {(file.size / 1024).toFixed(0)} KB\n </div>\n </>\n ) : (\n <div>📁 Click or drag &amp; drop to select a file</div>\n )}\n <input\n ref={inputRef}\n type=\"file\"\n accept={imagesOnly ? 'image/*' : '*/*'}\n style={{ display: 'none' }}\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) handleFile(f);\n }}\n />\n </div>\n {error && <Text color=\"critical.11\">{error}</Text>}\n </Stack>\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>\n {file?.name ?? 'No file selected'}\n </Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={onClose}>Cancel</Button>\n <Button\n variant=\"solid\"\n isDisabled={!file || uploading}\n onPress={() => file && onUpload(file, title, description)}\n >\n {uploading ? 'Uploading…' : 'Upload'}\n </Button>\n </Stack>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Library modal\n// ---------------------------------------------------------------------------\n\ninterface LibraryModalProps {\n files: MediaFile[];\n pagination: { currentPage: number; totalPages: number };\n loading: boolean;\n error: string | null;\n onNextPage: () => void;\n onPrevPage: () => void;\n onSelect: (file: MediaFile) => void;\n onClose: () => void;\n}\n\nconst LibraryModal: React.FC<LibraryModalProps> = ({\n files,\n pagination,\n loading,\n error,\n onNextPage,\n onPrevPage,\n onSelect,\n onClose,\n}) => {\n const [selected, setSelected] = useState<MediaFile | null>(null);\n\n const handleConfirm = () => {\n if (selected) onSelect(selected);\n };\n\n return (\n <div\n style={{\n position: 'fixed',\n inset: 0,\n background: 'rgba(0,0,0,0.5)',\n zIndex: 9999,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n onClick={(e) => e.target === e.currentTarget && onClose()}\n >\n <div\n style={{\n background: '#fff',\n borderRadius: '8px',\n width: '640px',\n maxWidth: '95vw',\n maxHeight: '85vh',\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '0 20px 60px rgba(0,0,0,0.3)',\n }}\n >\n {/* Header */}\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '16px 20px',\n borderBottom: '1px solid #e5e7eb',\n }}\n >\n <Text as=\"h4\" fontSize=\"xl\" fontWeight=\"700\">Select from Media Library</Text>\n <IconButton aria-label=\"Close\" variant=\"ghost\" size=\"xs\" onPress={onClose}>\n <Close />\n </IconButton>\n </div>\n\n {/* Body */}\n <div style={{ flex: 1, overflow: 'auto', padding: '20px' }}>\n {loading ? (\n <div style={{ display: 'flex', justifyContent: 'center', padding: '32px' }}>\n <LoadingSpinner />\n </div>\n ) : files.length === 0 ? (\n <Text color=\"neutral.11\">No files found.</Text>\n ) : (\n <Stack direction=\"column\" gap=\"400\">\n <div\n style={{\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(110px, 1fr))',\n gap: '12px',\n }}\n >\n {files.map((file) => (\n <div\n key={file.url}\n style={{\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n border: `2px solid ${selected?.url === file.url ? '#3b82f6' : 'transparent'}`,\n borderRadius: '6px',\n padding: '6px',\n background: selected?.url === file.url ? 'rgba(59,130,246,0.07)' : '#f9fafb',\n }}\n onClick={() => setSelected(file)}\n title={file.title ?? file.name}\n >\n {file.isImage ? (\n <img\n src={file.url}\n alt={file.name}\n style={{ width: '80px', height: '80px', objectFit: 'cover', borderRadius: '4px', background: '#e5e7eb' }}\n />\n ) : (\n <div\n style={{\n width: '80px',\n height: '80px',\n borderRadius: '4px',\n background: '#e5e7eb',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '28px',\n }}\n >\n 📄\n </div>\n )}\n <div\n style={{\n marginTop: '6px',\n fontSize: '11px',\n textAlign: 'center',\n maxWidth: '100%',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n color: '#374151',\n }}\n >\n {file.title ?? file.name}\n </div>\n </div>\n ))}\n </div>\n\n {pagination.totalPages > 1 && (\n <Stack direction=\"row\" gap=\"200\" alignItems=\"center\" justifyContent=\"center\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n isDisabled={pagination.currentPage <= 1}\n onPress={onPrevPage}\n >\n ← Prev\n </Button>\n <Text fontSize=\"sm\" color=\"neutral.11\">\n {pagination.currentPage} / {pagination.totalPages}\n </Text>\n <Button\n variant=\"outline\"\n size=\"sm\"\n isDisabled={pagination.currentPage >= pagination.totalPages}\n onPress={onNextPage}\n >\n Next →\n </Button>\n </Stack>\n )}\n </Stack>\n )}\n {error && <Text color=\"critical.11\">{error}</Text>}\n </div>\n\n {/* Footer */}\n <div\n style={{\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '12px 20px',\n borderTop: '1px solid #e5e7eb',\n gap: '12px',\n }}\n >\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>\n {selected ? (selected.title ?? selected.name) : 'Nothing selected'}\n </Text>\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={onClose}>Cancel</Button>\n <Button variant=\"solid\" isDisabled={!selected} onPress={handleConfirm}>\n Select\n </Button>\n </Stack>\n </div>\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// ImagePickerField — standalone field component\n// ---------------------------------------------------------------------------\n\nexport interface ImagePickerFieldProps {\n value: string;\n onChange: (value: string) => void;\n /** Only show images (default: true) */\n imagesOnly?: boolean;\n}\n\nexport const ImagePickerField: React.FC<ImagePickerFieldProps> = ({\n value,\n onChange,\n imagesOnly = true,\n}) => {\n const {\n files,\n pagination,\n loading,\n uploading,\n error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n } = useMediaLibrary();\n\n const [showUpload, setShowUpload] = useState(false);\n const [showLibrary, setShowLibrary] = useState(false);\n\n const extensions = imagesOnly ? ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg'] : [];\n\n const openLibrary = useCallback(() => {\n void fetchMedia(extensions, 1, 20);\n setShowLibrary(true);\n }, [fetchMedia, extensions]);\n\n const handleUpload = useCallback(\n async (file: File, title: string, description: string) => {\n const mediaFile = await uploadFile(file, title, description);\n onChange(mediaFile.url);\n setShowUpload(false);\n },\n [uploadFile, onChange]\n );\n\n const handleSelect = useCallback(\n (file: MediaFile) => {\n onChange(file.url);\n setShowLibrary(false);\n },\n [onChange]\n );\n\n // Close modals on Escape\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setShowUpload(false);\n setShowLibrary(false);\n }\n };\n window.addEventListener('keydown', onKey);\n return () => window.removeEventListener('keydown', onKey);\n }, []);\n\n return (\n <EnsureNimbusProvider>\n <Stack direction=\"column\" gap=\"200\">\n {value ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '10px',\n padding: '8px',\n border: '1px solid #d1d5db',\n borderRadius: '6px',\n background: '#f9fafb',\n }}\n >\n <img\n src={value}\n alt=\"\"\n style={{ width: '48px', height: '48px', objectFit: 'cover', borderRadius: '4px', flexShrink: 0 }}\n />\n <div style={{ flex: 1, minWidth: 0 }}>\n <Text fontSize=\"sm\" color=\"neutral.11\" truncate>{value}</Text>\n </div>\n <Button variant=\"ghost\" colorPalette=\"critical\" size=\"xs\" onPress={() => onChange('')}>\n Remove\n </Button>\n </div>\n ) : (\n <Text fontSize=\"sm\" color=\"neutral.11\">No image selected</Text>\n )}\n\n <Stack direction=\"row\" gap=\"200\">\n <Button variant=\"outline\" onPress={() => setShowUpload(true)}>Upload</Button>\n <Button variant=\"solid\" onPress={openLibrary}>Media Library</Button>\n </Stack>\n\n {showUpload && (\n <UploadModal\n uploading={uploading}\n error={error}\n imagesOnly={imagesOnly}\n onUpload={(file, title, desc) => void handleUpload(file, title, desc)}\n onClose={() => setShowUpload(false)}\n />\n )}\n\n {showLibrary && (\n <LibraryModal\n files={files}\n pagination={pagination}\n loading={loading}\n error={error}\n onNextPage={() => void loadNextPage(extensions)}\n onPrevPage={() => void loadPreviousPage(extensions)}\n onSelect={handleSelect}\n onClose={() => setShowLibrary(false)}\n />\n )}\n </Stack>\n </EnsureNimbusProvider>\n );\n};\n","import { useCallback, useState } from 'react';\nimport type {\n MediaFile,\n MediaLibraryPagination,\n} from '../types';\nimport {\n fetchMediaLibraryApi,\n uploadMediaFileApi,\n} from '../api/media-library.api';\nimport { useImagePickerContext } from '../context/ImagePickerContext';\n\ninterface MediaLibraryState {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n}\n\nconst initialPagination: MediaLibraryPagination = {\n totalItems: 0,\n totalPages: 0,\n currentPage: 1,\n limit: 20,\n};\n\nexport interface UseMediaLibraryReturn {\n files: MediaFile[];\n pagination: MediaLibraryPagination;\n loading: boolean;\n uploading: boolean;\n error: string | null;\n fetchMedia: (\n extensions?: string[],\n page?: number,\n limit?: number\n ) => Promise<void>;\n uploadFile: (\n file: File,\n title?: string,\n description?: string\n ) => Promise<MediaFile>;\n loadNextPage: (extensions?: string[]) => Promise<void>;\n loadPreviousPage: (extensions?: string[]) => Promise<void>;\n hasNextPage: () => boolean;\n hasPreviousPage: () => boolean;\n}\n\nexport const useMediaLibrary = (): UseMediaLibraryReturn => {\n const { baseURL, projectKey, businessUnitKey, jwtToken } =\n useImagePickerContext();\n\n const [state, setState] = useState<MediaLibraryState>({\n files: [],\n pagination: initialPagination,\n loading: false,\n uploading: false,\n error: null,\n });\n\n const fetchMedia = useCallback(\n async (\n extensions: string[] = [],\n page = 1,\n limit = 20\n ): Promise<void> => {\n setState((s) => ({ ...s, loading: true, error: null }));\n try {\n const result = await fetchMediaLibraryApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n extensions,\n page,\n limit\n );\n setState((s) => ({\n ...s,\n files: result.files,\n pagination: result.pagination,\n loading: false,\n }));\n } catch (err) {\n setState((s) => ({\n ...s,\n loading: false,\n error: (err as Error).message,\n }));\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const uploadFile = useCallback(\n async (\n file: File,\n title?: string,\n description?: string\n ): Promise<MediaFile> => {\n if (!jwtToken) throw new Error('jwtToken is required to upload files');\n setState((s) => ({ ...s, uploading: true, error: null }));\n try {\n const result = await uploadMediaFileApi(\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n file,\n title,\n description\n );\n const mediaFile: MediaFile = {\n url: result.url,\n name: file.name,\n title: title ?? file.name,\n description,\n isImage: file.type.startsWith('image/'),\n createdAt: new Date().toISOString(),\n size: file.size,\n };\n setState((s) => ({\n ...s,\n files: [mediaFile, ...s.files],\n pagination: {\n ...s.pagination,\n totalItems: s.pagination.totalItems + 1,\n },\n uploading: false,\n }));\n return mediaFile;\n } catch (err) {\n setState((s) => ({\n ...s,\n uploading: false,\n error: (err as Error).message,\n }));\n throw err;\n }\n },\n [baseURL, projectKey, businessUnitKey, jwtToken]\n );\n\n const loadNextPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const next = state.pagination.currentPage + 1;\n if (next <= state.pagination.totalPages) {\n await fetchMedia(extensions, next, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const loadPreviousPage = useCallback(\n async (extensions: string[] = []): Promise<void> => {\n const prev = state.pagination.currentPage - 1;\n if (prev >= 1) {\n await fetchMedia(extensions, prev, state.pagination.limit);\n }\n },\n [fetchMedia, state.pagination]\n );\n\n const hasNextPage = useCallback(\n () => state.pagination.currentPage < state.pagination.totalPages,\n [state.pagination]\n );\n\n const hasPreviousPage = useCallback(\n () => state.pagination.currentPage > 1,\n [state.pagination]\n );\n\n return {\n files: state.files,\n pagination: state.pagination,\n loading: state.loading,\n uploading: state.uploading,\n error: state.error,\n fetchMedia,\n uploadFile,\n loadNextPage,\n loadPreviousPage,\n hasNextPage,\n hasPreviousPage,\n };\n};\n","import type { MediaLibraryResult } from '../types';\n\n/**\n * Fetch media library files for a business unit.\n * Maps to GET /service/:businessUnitKey/media-library\n */\nexport const fetchMediaLibraryApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken?: string,\n extensions: string[] = [],\n page = 1,\n limit = 20\n): Promise<MediaLibraryResult> => {\n const params = new URLSearchParams();\n if (extensions.length > 0) params.set('extensions', extensions.join(','));\n params.set('page', String(page));\n params.set('limit', String(limit));\n\n const headers: Record<string, string> = {\n 'x-project-key': projectKey,\n };\n if (jwtToken) headers['Authorization'] = `Bearer ${jwtToken}`;\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/media-library?${params}`,\n { headers }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<MediaLibraryResult>;\n};\n\n/**\n * Upload a file for a business unit.\n * Maps to POST /service/:businessUnitKey/upload-file\n */\nexport const uploadMediaFileApi = async (\n baseURL: string,\n projectKey: string,\n businessUnitKey: string,\n jwtToken: string,\n file: File,\n title?: string,\n description?: string\n): Promise<{ url: string }> => {\n const formData = new FormData();\n formData.append('file', file);\n if (title) formData.append('title', title);\n if (description) formData.append('description', description);\n\n const res = await fetch(\n `${baseURL}/${businessUnitKey}/upload-file`,\n {\n method: 'POST',\n headers: {\n 'x-project-key': projectKey,\n Authorization: `Bearer ${jwtToken}`,\n },\n body: formData,\n }\n );\n\n if (!res.ok) {\n const body = await res.text();\n throw new Error(`[puck-image-picker] HTTP ${res.status}: ${body || res.statusText}`);\n }\n return res.json() as Promise<{ url: string }>;\n};\n","import { createContext, useContext } from 'react';\n\nexport interface ImagePickerConfig {\n baseURL: string;\n projectKey: string;\n businessUnitKey: string;\n jwtToken?: string;\n}\n\nexport const ImagePickerContext = createContext<ImagePickerConfig | null>(null);\n\nexport const useImagePickerContext = (): ImagePickerConfig => {\n const ctx = useContext(ImagePickerContext);\n if (!ctx) {\n throw new Error(\n 'useImagePickerContext must be used inside <ImagePickerProvider>. ' +\n 'Wrap your component tree with <ImagePickerProvider>.'\n );\n }\n return ctx;\n};\n","import React, { type PropsWithChildren } from 'react';\nimport { ChakraProvider, createSystem } from '@chakra-ui/react/styled-system';\nimport {\n NimbusI18nProvider,\n _RegionProvider,\n system as nimbusSystem,\n} from '@commercetools/nimbus';\n\n\nconst SCOPED_SYSTEM_KEY = Symbol.for(\n '@commercetools-demo/puck:nimbus-scoped-system'\n);\n\nconst globalScope = globalThis as unknown as Record<\n symbol,\n ReturnType<typeof createSystem> | undefined\n>;\n\nconst scopedSystem: ReturnType<typeof createSystem> =\n globalScope[SCOPED_SYSTEM_KEY] ??\n (globalScope[SCOPED_SYSTEM_KEY] = createSystem({\n // `_config` is the fully-merged Nimbus + Chakra config used to build the\n // stock system; reusing it keeps all Nimbus theming intact.\n ...(nimbusSystem as unknown as { _config: Record<string, unknown> })._config,\n preflight: false,\n globalCss: {},\n }));\n\nexport const EnsureNimbusProvider: React.FC<PropsWithChildren<{ locale?: string }>> = ({\n locale = 'en',\n children,\n}) => (\n <ChakraProvider value={scopedSystem}>\n <NimbusI18nProvider locale={locale}>\n <_RegionProvider>{children}</_RegionProvider>\n </NimbusI18nProvider>\n </ChakraProvider>\n);\n","import React, { type ReactNode } from 'react';\nimport { ImagePickerContext, type ImagePickerConfig } from './ImagePickerContext';\n\nexport interface ImagePickerProviderProps extends ImagePickerConfig {\n children: ReactNode;\n}\n\nexport const ImagePickerProvider: React.FC<ImagePickerProviderProps> = ({\n children,\n baseURL,\n projectKey,\n businessUnitKey,\n jwtToken,\n}) => {\n return (\n <ImagePickerContext.Provider\n value={{ baseURL, projectKey, businessUnitKey, jwtToken }}\n >\n {children}\n </ImagePickerContext.Provider>\n );\n};\n"],"mappings":"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","names":["import_react","import_react","import_nimbus","nimbusSystem","import_jsx_runtime","import_jsx_runtime"]}
package/dist/index.mjs CHANGED
@@ -196,17 +196,43 @@ var useMediaLibrary = () => {
196
196
  };
197
197
 
198
198
  // src/ImagePickerField.tsx
199
- import PrimaryButton from "@commercetools-uikit/primary-button";
200
- import SecondaryButton from "@commercetools-uikit/secondary-button";
201
- import FlatButton from "@commercetools-uikit/flat-button";
202
- import SecondaryIconButton from "@commercetools-uikit/secondary-icon-button";
203
- import TextInput from "@commercetools-uikit/text-input";
204
- import Label from "@commercetools-uikit/label";
205
- import LoadingSpinner from "@commercetools-uikit/loading-spinner";
206
- import Spacings from "@commercetools-uikit/spacings";
207
- import Text from "@commercetools-uikit/text";
208
- import { CloseIcon } from "@commercetools-uikit/icons";
209
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
199
+ import {
200
+ Button,
201
+ FormField,
202
+ IconButton,
203
+ LoadingSpinner,
204
+ Stack,
205
+ Text,
206
+ TextInput
207
+ } from "@commercetools/nimbus";
208
+ import { Close } from "@commercetools/nimbus-icons";
209
+
210
+ // src/EnsureNimbusProvider.tsx
211
+ import { ChakraProvider, createSystem } from "@chakra-ui/react/styled-system";
212
+ import {
213
+ NimbusI18nProvider,
214
+ _RegionProvider,
215
+ system as nimbusSystem
216
+ } from "@commercetools/nimbus";
217
+ import { jsx } from "react/jsx-runtime";
218
+ var SCOPED_SYSTEM_KEY = /* @__PURE__ */ Symbol.for(
219
+ "@commercetools-demo/puck:nimbus-scoped-system"
220
+ );
221
+ var globalScope = globalThis;
222
+ var scopedSystem = globalScope[SCOPED_SYSTEM_KEY] ?? (globalScope[SCOPED_SYSTEM_KEY] = createSystem({
223
+ // `_config` is the fully-merged Nimbus + Chakra config used to build the
224
+ // stock system; reusing it keeps all Nimbus theming intact.
225
+ ...nimbusSystem._config,
226
+ preflight: false,
227
+ globalCss: {}
228
+ }));
229
+ var EnsureNimbusProvider = ({
230
+ locale = "en",
231
+ children
232
+ }) => /* @__PURE__ */ jsx(ChakraProvider, { value: scopedSystem, children: /* @__PURE__ */ jsx(NimbusI18nProvider, { locale, children: /* @__PURE__ */ jsx(_RegionProvider, { children }) }) });
233
+
234
+ // src/ImagePickerField.tsx
235
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
210
236
  var UploadModal = ({
211
237
  uploading,
212
238
  error,
@@ -229,7 +255,7 @@ var UploadModal = ({
229
255
  const f = e.dataTransfer.files[0];
230
256
  if (f) handleFile(f);
231
257
  };
232
- return /* @__PURE__ */ jsx(
258
+ return /* @__PURE__ */ jsx2(
233
259
  "div",
234
260
  {
235
261
  style: {
@@ -267,43 +293,33 @@ var UploadModal = ({
267
293
  borderBottom: "1px solid #e5e7eb"
268
294
  },
269
295
  children: [
270
- /* @__PURE__ */ jsx(Text.Subheadline, { as: "h4", isBold: true, children: "Upload a file" }),
271
- /* @__PURE__ */ jsx(
272
- SecondaryIconButton,
273
- {
274
- icon: /* @__PURE__ */ jsx(CloseIcon, {}),
275
- label: "Close",
276
- onClick: onClose,
277
- size: "small"
278
- }
279
- )
296
+ /* @__PURE__ */ jsx2(Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Upload a file" }),
297
+ /* @__PURE__ */ jsx2(IconButton, { "aria-label": "Close", variant: "ghost", size: "xs", onPress: onClose, children: /* @__PURE__ */ jsx2(Close, {}) })
280
298
  ]
281
299
  }
282
300
  ),
283
- /* @__PURE__ */ jsx("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "m", children: [
284
- /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "xs", children: [
285
- /* @__PURE__ */ jsx(Label, { htmlFor: "upload-title", children: "Title" }),
286
- /* @__PURE__ */ jsx(
301
+ /* @__PURE__ */ jsx2("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: /* @__PURE__ */ jsxs(Stack, { direction: "column", gap: "400", children: [
302
+ /* @__PURE__ */ jsxs(FormField.Root, { children: [
303
+ /* @__PURE__ */ jsx2(FormField.Label, { children: "Title" }),
304
+ /* @__PURE__ */ jsx2(FormField.Input, { children: /* @__PURE__ */ jsx2(
287
305
  TextInput,
288
306
  {
289
- id: "upload-title",
290
307
  value: title,
291
- onChange: (e) => setTitle(e.target.value),
308
+ onChange: (value) => setTitle(value),
292
309
  placeholder: "File title"
293
310
  }
294
- )
311
+ ) })
295
312
  ] }),
296
- /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "xs", children: [
297
- /* @__PURE__ */ jsx(Label, { htmlFor: "upload-description", children: "Description" }),
298
- /* @__PURE__ */ jsx(
313
+ /* @__PURE__ */ jsxs(FormField.Root, { children: [
314
+ /* @__PURE__ */ jsx2(FormField.Label, { children: "Description" }),
315
+ /* @__PURE__ */ jsx2(FormField.Input, { children: /* @__PURE__ */ jsx2(
299
316
  TextInput,
300
317
  {
301
- id: "upload-description",
302
318
  value: description,
303
- onChange: (e) => setDescription(e.target.value),
319
+ onChange: (value) => setDescription(value),
304
320
  placeholder: "Optional description"
305
321
  }
306
- )
322
+ ) })
307
323
  ] }),
308
324
  /* @__PURE__ */ jsxs(
309
325
  "div",
@@ -335,8 +351,8 @@ var UploadModal = ({
335
351
  (file.size / 1024).toFixed(0),
336
352
  " KB"
337
353
  ] })
338
- ] }) : /* @__PURE__ */ jsx("div", { children: "\u{1F4C1} Click or drag & drop to select a file" }),
339
- /* @__PURE__ */ jsx(
354
+ ] }) : /* @__PURE__ */ jsx2("div", { children: "\u{1F4C1} Click or drag & drop to select a file" }),
355
+ /* @__PURE__ */ jsx2(
340
356
  "input",
341
357
  {
342
358
  ref: inputRef,
@@ -352,7 +368,7 @@ var UploadModal = ({
352
368
  ]
353
369
  }
354
370
  ),
355
- error && /* @__PURE__ */ jsx(Text.Body, { tone: "negative", children: error })
371
+ error && /* @__PURE__ */ jsx2(Text, { color: "critical.11", children: error })
356
372
  ] }) }),
357
373
  /* @__PURE__ */ jsxs(
358
374
  "div",
@@ -366,15 +382,16 @@ var UploadModal = ({
366
382
  gap: "12px"
367
383
  },
368
384
  children: [
369
- /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: file?.name ?? "No file selected" }),
370
- /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
371
- /* @__PURE__ */ jsx(SecondaryButton, { label: "Cancel", onClick: onClose }),
372
- /* @__PURE__ */ jsx(
373
- PrimaryButton,
385
+ /* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: file?.name ?? "No file selected" }),
386
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", children: [
387
+ /* @__PURE__ */ jsx2(Button, { variant: "outline", onPress: onClose, children: "Cancel" }),
388
+ /* @__PURE__ */ jsx2(
389
+ Button,
374
390
  {
375
- label: uploading ? "Uploading\u2026" : "Upload",
391
+ variant: "solid",
376
392
  isDisabled: !file || uploading,
377
- onClick: () => file && onUpload(file, title, description)
393
+ onPress: () => file && onUpload(file, title, description),
394
+ children: uploading ? "Uploading\u2026" : "Upload"
378
395
  }
379
396
  )
380
397
  ] })
@@ -401,7 +418,7 @@ var LibraryModal = ({
401
418
  const handleConfirm = () => {
402
419
  if (selected) onSelect(selected);
403
420
  };
404
- return /* @__PURE__ */ jsx(
421
+ return /* @__PURE__ */ jsx2(
405
422
  "div",
406
423
  {
407
424
  style: {
@@ -439,22 +456,14 @@ var LibraryModal = ({
439
456
  borderBottom: "1px solid #e5e7eb"
440
457
  },
441
458
  children: [
442
- /* @__PURE__ */ jsx(Text.Subheadline, { as: "h4", isBold: true, children: "Select from Media Library" }),
443
- /* @__PURE__ */ jsx(
444
- SecondaryIconButton,
445
- {
446
- icon: /* @__PURE__ */ jsx(CloseIcon, {}),
447
- label: "Close",
448
- onClick: onClose,
449
- size: "small"
450
- }
451
- )
459
+ /* @__PURE__ */ jsx2(Text, { as: "h4", fontSize: "xl", fontWeight: "700", children: "Select from Media Library" }),
460
+ /* @__PURE__ */ jsx2(IconButton, { "aria-label": "Close", variant: "ghost", size: "xs", onPress: onClose, children: /* @__PURE__ */ jsx2(Close, {}) })
452
461
  ]
453
462
  }
454
463
  ),
455
464
  /* @__PURE__ */ jsxs("div", { style: { flex: 1, overflow: "auto", padding: "20px" }, children: [
456
- loading ? /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }) : files.length === 0 ? /* @__PURE__ */ jsx(Text.Body, { tone: "secondary", children: "No files found." }) : /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "m", children: [
457
- /* @__PURE__ */ jsx(
465
+ loading ? /* @__PURE__ */ jsx2("div", { style: { display: "flex", justifyContent: "center", padding: "32px" }, children: /* @__PURE__ */ jsx2(LoadingSpinner, {}) }) : files.length === 0 ? /* @__PURE__ */ jsx2(Text, { color: "neutral.11", children: "No files found." }) : /* @__PURE__ */ jsxs(Stack, { direction: "column", gap: "400", children: [
466
+ /* @__PURE__ */ jsx2(
458
467
  "div",
459
468
  {
460
469
  style: {
@@ -478,14 +487,14 @@ var LibraryModal = ({
478
487
  onClick: () => setSelected(file),
479
488
  title: file.title ?? file.name,
480
489
  children: [
481
- file.isImage ? /* @__PURE__ */ jsx(
490
+ file.isImage ? /* @__PURE__ */ jsx2(
482
491
  "img",
483
492
  {
484
493
  src: file.url,
485
494
  alt: file.name,
486
495
  style: { width: "80px", height: "80px", objectFit: "cover", borderRadius: "4px", background: "#e5e7eb" }
487
496
  }
488
- ) : /* @__PURE__ */ jsx(
497
+ ) : /* @__PURE__ */ jsx2(
489
498
  "div",
490
499
  {
491
500
  style: {
@@ -501,7 +510,7 @@ var LibraryModal = ({
501
510
  children: "\u{1F4C4}"
502
511
  }
503
512
  ),
504
- /* @__PURE__ */ jsx(
513
+ /* @__PURE__ */ jsx2(
505
514
  "div",
506
515
  {
507
516
  style: {
@@ -523,33 +532,35 @@ var LibraryModal = ({
523
532
  ))
524
533
  }
525
534
  ),
526
- pagination.totalPages > 1 && /* @__PURE__ */ jsxs(Spacings.Inline, { alignItems: "center", justifyContent: "center", scale: "s", children: [
527
- /* @__PURE__ */ jsx(
528
- SecondaryButton,
535
+ pagination.totalPages > 1 && /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", alignItems: "center", justifyContent: "center", children: [
536
+ /* @__PURE__ */ jsx2(
537
+ Button,
529
538
  {
530
- label: "\u2190 Prev",
539
+ variant: "outline",
540
+ size: "sm",
531
541
  isDisabled: pagination.currentPage <= 1,
532
- onClick: onPrevPage,
533
- size: "small"
542
+ onPress: onPrevPage,
543
+ children: "\u2190 Prev"
534
544
  }
535
545
  ),
536
- /* @__PURE__ */ jsxs(Text.Detail, { tone: "secondary", children: [
546
+ /* @__PURE__ */ jsxs(Text, { fontSize: "sm", color: "neutral.11", children: [
537
547
  pagination.currentPage,
538
548
  " / ",
539
549
  pagination.totalPages
540
550
  ] }),
541
- /* @__PURE__ */ jsx(
542
- SecondaryButton,
551
+ /* @__PURE__ */ jsx2(
552
+ Button,
543
553
  {
544
- label: "Next \u2192",
554
+ variant: "outline",
555
+ size: "sm",
545
556
  isDisabled: pagination.currentPage >= pagination.totalPages,
546
- onClick: onNextPage,
547
- size: "small"
557
+ onPress: onNextPage,
558
+ children: "Next \u2192"
548
559
  }
549
560
  )
550
561
  ] })
551
562
  ] }),
552
- error && /* @__PURE__ */ jsx(Text.Body, { tone: "negative", children: error })
563
+ error && /* @__PURE__ */ jsx2(Text, { color: "critical.11", children: error })
553
564
  ] }),
554
565
  /* @__PURE__ */ jsxs(
555
566
  "div",
@@ -563,17 +574,10 @@ var LibraryModal = ({
563
574
  gap: "12px"
564
575
  },
565
576
  children: [
566
- /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: selected ? selected.title ?? selected.name : "Nothing selected" }),
567
- /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
568
- /* @__PURE__ */ jsx(SecondaryButton, { label: "Cancel", onClick: onClose }),
569
- /* @__PURE__ */ jsx(
570
- PrimaryButton,
571
- {
572
- label: "Select",
573
- isDisabled: !selected,
574
- onClick: handleConfirm
575
- }
576
- )
577
+ /* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: selected ? selected.title ?? selected.name : "Nothing selected" }),
578
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", children: [
579
+ /* @__PURE__ */ jsx2(Button, { variant: "outline", onPress: onClose, children: "Cancel" }),
580
+ /* @__PURE__ */ jsx2(Button, { variant: "solid", isDisabled: !selected, onPress: handleConfirm, children: "Select" })
577
581
  ] })
578
582
  ]
579
583
  }
@@ -632,7 +636,7 @@ var ImagePickerField = ({
632
636
  window.addEventListener("keydown", onKey);
633
637
  return () => window.removeEventListener("keydown", onKey);
634
638
  }, []);
635
- return /* @__PURE__ */ jsxs(Spacings.Stack, { scale: "s", children: [
639
+ return /* @__PURE__ */ jsx2(EnsureNimbusProvider, { children: /* @__PURE__ */ jsxs(Stack, { direction: "column", gap: "200", children: [
636
640
  value ? /* @__PURE__ */ jsxs(
637
641
  "div",
638
642
  {
@@ -646,7 +650,7 @@ var ImagePickerField = ({
646
650
  background: "#f9fafb"
647
651
  },
648
652
  children: [
649
- /* @__PURE__ */ jsx(
653
+ /* @__PURE__ */ jsx2(
650
654
  "img",
651
655
  {
652
656
  src: value,
@@ -654,16 +658,16 @@ var ImagePickerField = ({
654
658
  style: { width: "48px", height: "48px", objectFit: "cover", borderRadius: "4px", flexShrink: 0 }
655
659
  }
656
660
  ),
657
- /* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", truncate: true, children: value }) }),
658
- /* @__PURE__ */ jsx(FlatButton, { tone: "critical", label: "Remove", onClick: () => onChange("") })
661
+ /* @__PURE__ */ jsx2("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", truncate: true, children: value }) }),
662
+ /* @__PURE__ */ jsx2(Button, { variant: "ghost", colorPalette: "critical", size: "xs", onPress: () => onChange(""), children: "Remove" })
659
663
  ]
660
664
  }
661
- ) : /* @__PURE__ */ jsx(Text.Detail, { tone: "secondary", children: "No image selected" }),
662
- /* @__PURE__ */ jsxs(Spacings.Inline, { scale: "s", children: [
663
- /* @__PURE__ */ jsx(SecondaryButton, { label: "Upload", onClick: () => setShowUpload(true) }),
664
- /* @__PURE__ */ jsx(PrimaryButton, { label: "Media Library", onClick: openLibrary })
665
+ ) : /* @__PURE__ */ jsx2(Text, { fontSize: "sm", color: "neutral.11", children: "No image selected" }),
666
+ /* @__PURE__ */ jsxs(Stack, { direction: "row", gap: "200", children: [
667
+ /* @__PURE__ */ jsx2(Button, { variant: "outline", onPress: () => setShowUpload(true), children: "Upload" }),
668
+ /* @__PURE__ */ jsx2(Button, { variant: "solid", onPress: openLibrary, children: "Media Library" })
665
669
  ] }),
666
- showUpload && /* @__PURE__ */ jsx(
670
+ showUpload && /* @__PURE__ */ jsx2(
667
671
  UploadModal,
668
672
  {
669
673
  uploading,
@@ -673,7 +677,7 @@ var ImagePickerField = ({
673
677
  onClose: () => setShowUpload(false)
674
678
  }
675
679
  ),
676
- showLibrary && /* @__PURE__ */ jsx(
680
+ showLibrary && /* @__PURE__ */ jsx2(
677
681
  LibraryModal,
678
682
  {
679
683
  files,
@@ -686,11 +690,11 @@ var ImagePickerField = ({
686
690
  onClose: () => setShowLibrary(false)
687
691
  }
688
692
  )
689
- ] });
693
+ ] }) });
690
694
  };
691
695
 
692
696
  // src/context/ImagePickerProvider.tsx
693
- import { jsx as jsx2 } from "react/jsx-runtime";
697
+ import { jsx as jsx3 } from "react/jsx-runtime";
694
698
  var ImagePickerProvider = ({
695
699
  children,
696
700
  baseURL,
@@ -698,7 +702,7 @@ var ImagePickerProvider = ({
698
702
  businessUnitKey,
699
703
  jwtToken
700
704
  }) => {
701
- return /* @__PURE__ */ jsx2(
705
+ return /* @__PURE__ */ jsx3(
702
706
  ImagePickerContext.Provider,
703
707
  {
704
708
  value: { baseURL, projectKey, businessUnitKey, jwtToken },