@valu/block-components 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,210 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ type DocumentPickerVariant = 'popover' | 'inline';
5
+ /** Reason a picked document can't be displayed normally. */
6
+ type MissingReason = 'deleted';
7
+ /**
8
+ * A document item in the picker. `key` is a stable client-side uuid (use
9
+ * for React keys); `id` is the WordPress attachment id.
10
+ */
11
+ interface DocumentItem {
12
+ key: string;
13
+ id: number;
14
+ title: string;
15
+ filename: string;
16
+ url: string;
17
+ mimeType: string;
18
+ /** Uppercase extension, e.g. `PDF`, `DOCX`. Empty string if unknown. */
19
+ extension: string;
20
+ /** File size in bytes (from `media_details.filesize` when available). */
21
+ fileSize?: number;
22
+ /** ISO-8601 date string of the last modification, when available. */
23
+ modified?: string;
24
+ /** Raw REST record so consumer filters can reach beyond the normalized shape. */
25
+ raw?: unknown;
26
+ }
27
+ /** A picked document resolved against the current entity store. */
28
+ interface ResolvedDocumentItem extends DocumentItem {
29
+ missing?: MissingReason;
30
+ }
31
+ /** i18n bag — all optional, sensible defaults are used. */
32
+ interface DocumentPickerLabels {
33
+ input?: string;
34
+ help?: string;
35
+ empty?: string;
36
+ loading?: string;
37
+ noDocumentsFound?: string;
38
+ selectedSingular?: string;
39
+ selectedPlural?: string;
40
+ limitReached?: string;
41
+ browseMediaLibrary?: string;
42
+ replace?: string;
43
+ remove?: string;
44
+ moveUp?: string;
45
+ moveDown?: string;
46
+ dragHandle?: string;
47
+ missing?: string;
48
+ openLink?: string;
49
+ extensionBadge?: string;
50
+ }
51
+ interface RequestContext {
52
+ query: string;
53
+ page: number;
54
+ }
55
+ interface FilterContext {
56
+ query: string;
57
+ }
58
+ interface SuggestionRenderState {
59
+ highlighted: boolean;
60
+ selected: boolean;
61
+ }
62
+ interface DocumentPickerProps {
63
+ /** Accessible name. Required. */
64
+ label: string;
65
+ /** Hide the label visually but keep it for screen readers. */
66
+ hideLabelFromVision?: boolean;
67
+ /** Help text shown under the input. */
68
+ help?: string;
69
+ /** Visual variant. @default 'popover' */
70
+ variant?: DocumentPickerVariant;
71
+ /** Controlled value. Omit for uncontrolled. */
72
+ value?: DocumentItem[];
73
+ /** Uncontrolled initial value. */
74
+ defaultValue?: DocumentItem[];
75
+ /** Called with the next array whenever the selection changes. */
76
+ onChange?: (items: DocumentItem[]) => void;
77
+ /** Maximum items the user can pick. `1` = single-select. @default Infinity */
78
+ maxItems?: number;
79
+ /** Allow drag-to-reorder. @default true when maxItems > 1 */
80
+ orderable?: boolean;
81
+ /** Input placeholder text. */
82
+ placeholder?: string;
83
+ /**
84
+ * MIME types to filter REST search and forward to the Media Library modal.
85
+ * @default DEFAULT_DOCUMENT_MIME_TYPES (PDF, Word, Excel, PowerPoint)
86
+ */
87
+ allowedMimeTypes?: string[];
88
+ /**
89
+ * Additional file extensions to accept (matched case-insensitively
90
+ * against the basename). Useful for documents with non-standard MIME.
91
+ */
92
+ allowedExtensions?: string[];
93
+ /** Items per page from the REST search endpoint. @default 10 (popover) / 20 (inline) */
94
+ perPage?: number;
95
+ /** Debounce between keystrokes and the search request, in ms. @default 250 */
96
+ inputDelayMs?: number;
97
+ /** In `popover` variant, fetch suggestions immediately when the popover opens. */
98
+ fetchOnOpen?: boolean;
99
+ /** Prevent duplicate items in the selection. @default true */
100
+ uniqueItems?: boolean;
101
+ /** Show the "Browse Media Library" button. @default true */
102
+ enableMediaLibrary?: boolean;
103
+ /** Show the uppercase extension badge on each row. @default true */
104
+ showExtensionBadge?: boolean;
105
+ /** Show file size on each row. @default true */
106
+ showFileSize?: boolean;
107
+ /** Show the upload/modified date on each row. @default false */
108
+ showModifiedDate?: boolean;
109
+ /** Final filter over normalized suggestions. */
110
+ filter?: (items: DocumentItem[], ctx: FilterContext) => DocumentItem[];
111
+ /** Rewrite the REST path before it is fetched. */
112
+ request?: (path: string, ctx: RequestContext) => string;
113
+ /** Custom suggestion-row renderer. */
114
+ renderSuggestion?: (item: DocumentItem, state: SuggestionRenderState) => ReactNode;
115
+ /** Custom selected-row renderer. */
116
+ renderSelected?: (item: ResolvedDocumentItem) => ReactNode;
117
+ /** i18n overrides. */
118
+ labels?: DocumentPickerLabels;
119
+ /** Extra class on the root element. */
120
+ className?: string;
121
+ /** Explicit id for the root element; used as prefix for ARIA ids. */
122
+ id?: string;
123
+ }
124
+
125
+ /**
126
+ * `<DocumentPicker />` — search for and attach WordPress document attachments
127
+ * (PDFs, Word, Excel, PowerPoint by default) to a block. Combines a fast
128
+ * REST-search popover/inline list with WordPress's native Media Library modal
129
+ * for browsing and uploading.
130
+ *
131
+ * The component is **controlled** when `value` is defined and **uncontrolled**
132
+ * (with optional `defaultValue`) otherwise. In both modes `onChange` fires
133
+ * with the full next array.
134
+ *
135
+ * @example
136
+ * <DocumentPicker
137
+ * label="Downloadable documents"
138
+ * value={attributes.documents}
139
+ * onChange={(items) => setAttributes({ documents: items })}
140
+ * />
141
+ */
142
+ declare const DocumentPicker: ({ label, hideLabelFromVision, help, variant, value: controlledValue, defaultValue, onChange, maxItems, orderable, placeholder, allowedMimeTypes, allowedExtensions, perPage, inputDelayMs, fetchOnOpen, uniqueItems, enableMediaLibrary, showExtensionBadge, showFileSize, showModifiedDate, filter, request, renderSuggestion, renderSelected, labels, className, id, }: DocumentPickerProps) => react_jsx_runtime.JSX.Element;
143
+
144
+ interface MediaLibraryButtonProps {
145
+ allowedMimeTypes: string[];
146
+ allowedExtensions?: string[];
147
+ multiple: boolean;
148
+ value: DocumentItem[];
149
+ onSelect: (items: DocumentItem[]) => void;
150
+ labels: DocumentPickerLabels;
151
+ disabled?: boolean;
152
+ variant?: 'primary' | 'secondary' | 'tertiary';
153
+ label?: string;
154
+ }
155
+ declare const MediaLibraryButton: ({ allowedMimeTypes, allowedExtensions, multiple, value, onSelect, labels, disabled, variant, label, }: MediaLibraryButtonProps) => react_jsx_runtime.JSX.Element;
156
+
157
+ interface ExtensionBadgeProps {
158
+ extension: string;
159
+ /** Override of the visible label (defaults to the uppercase extension). */
160
+ label?: string;
161
+ }
162
+ declare const ExtensionBadge: ({ extension, label }: ExtensionBadgeProps) => react_jsx_runtime.JSX.Element;
163
+
164
+ interface FileSizeProps {
165
+ bytes: number | undefined;
166
+ }
167
+ declare const FileSize: ({ bytes }: FileSizeProps) => react_jsx_runtime.JSX.Element | null;
168
+
169
+ /**
170
+ * Default MIME types treated as "documents": PDF, Word, Excel, PowerPoint
171
+ * (both legacy and Office Open XML variants).
172
+ */
173
+ declare const DEFAULT_DOCUMENT_MIME_TYPES: readonly string[];
174
+ /** Extract the basename from a URL/path. Strips query and hash. */
175
+ declare const basenameFromUrl: (url: string | undefined | null) => string;
176
+ /** Uppercase extension from a URL or filename. `''` if none. */
177
+ declare const extensionFromUrl: (url: string | undefined | null) => string;
178
+ /**
179
+ * Human-readable file size. Mirrors the `wp_format_bytes()` style used in
180
+ * WP admin (1 KB = 1024 B). Returns an empty string when the input is
181
+ * undefined or non-positive.
182
+ */
183
+ declare const formatFileSize: (bytes: number | undefined) => string;
184
+ interface MediaRecordShape {
185
+ id: number;
186
+ title?: {
187
+ rendered?: string;
188
+ } | string;
189
+ source_url?: string;
190
+ url?: string;
191
+ mime_type?: string;
192
+ mime?: string;
193
+ media_details?: {
194
+ filesize?: number;
195
+ original_image?: string;
196
+ };
197
+ modified?: string;
198
+ modified_gmt?: string;
199
+ date?: string;
200
+ filename?: string;
201
+ link?: string;
202
+ }
203
+ /**
204
+ * Normalize a record from `/wp/v2/media` (or from `MediaUpload.onSelect`)
205
+ * into a `DocumentItem`. Tolerant of both shapes — `source_url`/`url`,
206
+ * `mime_type`/`mime`, etc.
207
+ */
208
+ declare const mapMediaToDocumentItem: (raw: MediaRecordShape) => DocumentItem;
209
+
210
+ export { DEFAULT_DOCUMENT_MIME_TYPES, type DocumentItem, DocumentPicker, type DocumentPickerLabels, type DocumentPickerProps, type DocumentPickerVariant, ExtensionBadge, FileSize, type FilterContext, MediaLibraryButton, type MissingReason, type RequestContext, type ResolvedDocumentItem, type SuggestionRenderState, basenameFromUrl, extensionFromUrl, formatFileSize, mapMediaToDocumentItem };