@shipstatic/drop 0.1.19 → 0.2.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.d.cts CHANGED
@@ -1,164 +1,7 @@
1
- import { ValidationError } from '@shipstatic/types';
2
- import { Ship, formatFileSize as formatFileSize$1 } from '@shipstatic/ship';
3
-
4
- /**
5
- * Core types for @shipstatic/drop
6
- * Imports types from @shipstatic/types (single source of truth)
7
- * and defines drop-specific types
8
- */
9
-
10
- /**
11
- * Extended File interface with webkitRelativePath
12
- * This property is set by browsers for folder uploads and drag-drop
13
- * https://developer.mozilla.org/en-US/docs/Web/API/File/webkitRelativePath
14
- */
15
- interface FileWithPath extends File {
16
- readonly webkitRelativePath: string;
17
- }
18
- declare const FILE_STATUSES: {
19
- readonly PROCESSING: "processing";
20
- readonly UPLOADING: "uploading";
21
- readonly COMPLETE: "complete";
22
- readonly ERROR: "error";
23
- readonly PENDING: "pending";
24
- readonly PROCESSING_ERROR: "processing_error";
25
- readonly EMPTY_FILE: "empty_file";
26
- readonly VALIDATION_FAILED: "validation_failed";
27
- readonly READY: "ready";
28
- };
29
- type FileStatus = (typeof FILE_STATUSES)[keyof typeof FILE_STATUSES];
30
- /**
31
- * Client-side error structure
32
- * Matches ValidationError from @shipstatic/ship for consistency
33
- */
34
- type ClientError = ValidationError;
35
- /**
36
- * Processed file entry ready for upload
37
- * Contains both the File object and UI-specific metadata
38
- * Use `file` property to access the underlying File for SDK operations
39
- */
40
- interface ProcessedFile {
41
- /** Unique identifier for React keys and tracking */
42
- id: string;
43
- /** The File object - pass this to ship.deployments.create() */
44
- file: File;
45
- /** Relative path for deployment (e.g., "images/photo.jpg") */
46
- path: string;
47
- /** File size in bytes */
48
- size: number;
49
- /** MD5 hash (optional - Ship SDK calculates during deployment if not provided) */
50
- md5?: string;
51
- /** Filename without path */
52
- name: string;
53
- /** MIME type for UI icons/previews */
54
- type: string;
55
- /** Last modified timestamp */
56
- lastModified: number;
57
- /** Current processing/upload status */
58
- status: FileStatus;
59
- /** Human-readable status message for UI */
60
- statusMessage?: string;
61
- /** Upload progress (0-100) - only set during upload */
62
- progress?: number;
63
- }
64
- /**
65
- * State machine values for the drop hook
66
- */
67
- type DropStateValue = 'idle' | 'dragging' | 'processing' | 'ready' | 'error';
68
- /**
69
- * Status information with title and details
70
- */
71
- interface DropStatus {
72
- title: string;
73
- details: string;
74
- errors?: string[];
75
- }
76
- /**
77
- * State machine state for the drop hook
78
- */
79
- interface DropState {
80
- value: DropStateValue;
81
- files: ProcessedFile[];
82
- sourceName: string;
83
- status: DropStatus | null;
84
- }
85
-
86
- interface DropOptions {
87
- /** Ship SDK instance (required for validation) */
88
- ship: Ship;
89
- /** Callback when files are processed and ready */
90
- onFilesReady?: (files: ProcessedFile[]) => void;
91
- /** Callback when validation fails */
92
- onValidationError?: (error: ClientError) => void;
93
- /** Whether to strip common directory prefix from paths (default: true) */
94
- stripPrefix?: boolean;
95
- }
96
- interface DropReturn {
97
- /** Current phase of the state machine */
98
- phase: DropStateValue;
99
- /** Whether currently processing files (ZIP extraction, etc.) */
100
- isProcessing: boolean;
101
- /** Whether user is currently dragging over the dropzone */
102
- isDragging: boolean;
103
- /** Flattened access to files */
104
- files: ProcessedFile[];
105
- /** Flattened access to source name */
106
- sourceName: string;
107
- /** Flattened access to status */
108
- status: {
109
- title: string;
110
- details: string;
111
- errors?: string[];
112
- } | null;
113
- /** Get props to spread on dropzone element (handles drag & drop) */
114
- getDropzoneProps: () => {
115
- onDragOver: (e: React.DragEvent) => void;
116
- onDragLeave: (e: React.DragEvent) => void;
117
- onDrop: (e: React.DragEvent) => void;
118
- onClick: () => void;
119
- };
120
- /** Get props to spread on hidden file input element */
121
- getInputProps: () => {
122
- ref: React.RefObject<HTMLInputElement | null>;
123
- type: 'file';
124
- style: {
125
- display: string;
126
- };
127
- multiple: boolean;
128
- webkitdirectory: string;
129
- onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
130
- };
131
- /** Programmatically trigger file picker */
132
- open: () => void;
133
- /** Manually process files (for advanced usage) */
134
- processFiles: (files: File[]) => Promise<void>;
135
- /** Clear all files and reset state */
136
- clearAll: () => void;
137
- /** Get only valid files ready for upload */
138
- validFiles: ProcessedFile[];
139
- /** Update upload state for a specific file (status, progress, message) */
140
- updateFileStatus: (fileId: string, state: {
141
- status: FileStatus;
142
- statusMessage?: string;
143
- progress?: number;
144
- }) => void;
145
- }
146
- /**
147
- * Headless drop hook for file upload workflows
148
- *
149
- * @example
150
- * ```tsx
151
- * const drop = useDrop({ ship });
152
- *
153
- * return (
154
- * <div {...drop.getDropzoneProps()} style={{...}}>
155
- * <input {...drop.getInputProps()} />
156
- * {drop.isDragging ? "📂 Drop" : "📁 Click"}
157
- * </div>
158
- * );
159
- * ```
160
- */
161
- declare function useDrop(options: DropOptions): DropReturn;
1
+ import { P as ProcessedFile } from './useDrop-CRUVkVzW.cjs';
2
+ export { C as ClientError, D as DropOptions, a as DropReturn, b as DropState, c as DropStateValue, d as DropStatus, e as DropzonePropsOptions, F as FILE_STATUSES, f as FileStatus, g as FileWithPath, u as useDrop } from './useDrop-CRUVkVzW.cjs';
3
+ import { formatFileSize as formatFileSize$1 } from '@shipstatic/ship';
4
+ import '@shipstatic/types';
162
5
 
163
6
  /**
164
7
  * Unified file processing utilities
@@ -227,4 +70,4 @@ declare function isZipFile(file: File): boolean;
227
70
  */
228
71
  declare function getMimeType(path: string): string;
229
72
 
230
- export { type ClientError, type DropOptions, type DropReturn, type DropState, type DropStateValue, type DropStatus, FILE_STATUSES, type FileStatus, type FileWithPath, type ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize, getMimeType, isZipFile, normalizePath, stripCommonPrefix, traverseFileTree, useDrop };
73
+ export { ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize, getMimeType, isZipFile, normalizePath, stripCommonPrefix, traverseFileTree };
package/dist/index.d.ts CHANGED
@@ -1,164 +1,7 @@
1
- import { ValidationError } from '@shipstatic/types';
2
- import { Ship, formatFileSize as formatFileSize$1 } from '@shipstatic/ship';
3
-
4
- /**
5
- * Core types for @shipstatic/drop
6
- * Imports types from @shipstatic/types (single source of truth)
7
- * and defines drop-specific types
8
- */
9
-
10
- /**
11
- * Extended File interface with webkitRelativePath
12
- * This property is set by browsers for folder uploads and drag-drop
13
- * https://developer.mozilla.org/en-US/docs/Web/API/File/webkitRelativePath
14
- */
15
- interface FileWithPath extends File {
16
- readonly webkitRelativePath: string;
17
- }
18
- declare const FILE_STATUSES: {
19
- readonly PROCESSING: "processing";
20
- readonly UPLOADING: "uploading";
21
- readonly COMPLETE: "complete";
22
- readonly ERROR: "error";
23
- readonly PENDING: "pending";
24
- readonly PROCESSING_ERROR: "processing_error";
25
- readonly EMPTY_FILE: "empty_file";
26
- readonly VALIDATION_FAILED: "validation_failed";
27
- readonly READY: "ready";
28
- };
29
- type FileStatus = (typeof FILE_STATUSES)[keyof typeof FILE_STATUSES];
30
- /**
31
- * Client-side error structure
32
- * Matches ValidationError from @shipstatic/ship for consistency
33
- */
34
- type ClientError = ValidationError;
35
- /**
36
- * Processed file entry ready for upload
37
- * Contains both the File object and UI-specific metadata
38
- * Use `file` property to access the underlying File for SDK operations
39
- */
40
- interface ProcessedFile {
41
- /** Unique identifier for React keys and tracking */
42
- id: string;
43
- /** The File object - pass this to ship.deployments.create() */
44
- file: File;
45
- /** Relative path for deployment (e.g., "images/photo.jpg") */
46
- path: string;
47
- /** File size in bytes */
48
- size: number;
49
- /** MD5 hash (optional - Ship SDK calculates during deployment if not provided) */
50
- md5?: string;
51
- /** Filename without path */
52
- name: string;
53
- /** MIME type for UI icons/previews */
54
- type: string;
55
- /** Last modified timestamp */
56
- lastModified: number;
57
- /** Current processing/upload status */
58
- status: FileStatus;
59
- /** Human-readable status message for UI */
60
- statusMessage?: string;
61
- /** Upload progress (0-100) - only set during upload */
62
- progress?: number;
63
- }
64
- /**
65
- * State machine values for the drop hook
66
- */
67
- type DropStateValue = 'idle' | 'dragging' | 'processing' | 'ready' | 'error';
68
- /**
69
- * Status information with title and details
70
- */
71
- interface DropStatus {
72
- title: string;
73
- details: string;
74
- errors?: string[];
75
- }
76
- /**
77
- * State machine state for the drop hook
78
- */
79
- interface DropState {
80
- value: DropStateValue;
81
- files: ProcessedFile[];
82
- sourceName: string;
83
- status: DropStatus | null;
84
- }
85
-
86
- interface DropOptions {
87
- /** Ship SDK instance (required for validation) */
88
- ship: Ship;
89
- /** Callback when files are processed and ready */
90
- onFilesReady?: (files: ProcessedFile[]) => void;
91
- /** Callback when validation fails */
92
- onValidationError?: (error: ClientError) => void;
93
- /** Whether to strip common directory prefix from paths (default: true) */
94
- stripPrefix?: boolean;
95
- }
96
- interface DropReturn {
97
- /** Current phase of the state machine */
98
- phase: DropStateValue;
99
- /** Whether currently processing files (ZIP extraction, etc.) */
100
- isProcessing: boolean;
101
- /** Whether user is currently dragging over the dropzone */
102
- isDragging: boolean;
103
- /** Flattened access to files */
104
- files: ProcessedFile[];
105
- /** Flattened access to source name */
106
- sourceName: string;
107
- /** Flattened access to status */
108
- status: {
109
- title: string;
110
- details: string;
111
- errors?: string[];
112
- } | null;
113
- /** Get props to spread on dropzone element (handles drag & drop) */
114
- getDropzoneProps: () => {
115
- onDragOver: (e: React.DragEvent) => void;
116
- onDragLeave: (e: React.DragEvent) => void;
117
- onDrop: (e: React.DragEvent) => void;
118
- onClick: () => void;
119
- };
120
- /** Get props to spread on hidden file input element */
121
- getInputProps: () => {
122
- ref: React.RefObject<HTMLInputElement | null>;
123
- type: 'file';
124
- style: {
125
- display: string;
126
- };
127
- multiple: boolean;
128
- webkitdirectory: string;
129
- onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
130
- };
131
- /** Programmatically trigger file picker */
132
- open: () => void;
133
- /** Manually process files (for advanced usage) */
134
- processFiles: (files: File[]) => Promise<void>;
135
- /** Clear all files and reset state */
136
- clearAll: () => void;
137
- /** Get only valid files ready for upload */
138
- validFiles: ProcessedFile[];
139
- /** Update upload state for a specific file (status, progress, message) */
140
- updateFileStatus: (fileId: string, state: {
141
- status: FileStatus;
142
- statusMessage?: string;
143
- progress?: number;
144
- }) => void;
145
- }
146
- /**
147
- * Headless drop hook for file upload workflows
148
- *
149
- * @example
150
- * ```tsx
151
- * const drop = useDrop({ ship });
152
- *
153
- * return (
154
- * <div {...drop.getDropzoneProps()} style={{...}}>
155
- * <input {...drop.getInputProps()} />
156
- * {drop.isDragging ? "📂 Drop" : "📁 Click"}
157
- * </div>
158
- * );
159
- * ```
160
- */
161
- declare function useDrop(options: DropOptions): DropReturn;
1
+ import { P as ProcessedFile } from './useDrop-CRUVkVzW.js';
2
+ export { C as ClientError, D as DropOptions, a as DropReturn, b as DropState, c as DropStateValue, d as DropStatus, e as DropzonePropsOptions, F as FILE_STATUSES, f as FileStatus, g as FileWithPath, u as useDrop } from './useDrop-CRUVkVzW.js';
3
+ import { formatFileSize as formatFileSize$1 } from '@shipstatic/ship';
4
+ import '@shipstatic/types';
162
5
 
163
6
  /**
164
7
  * Unified file processing utilities
@@ -227,4 +70,4 @@ declare function isZipFile(file: File): boolean;
227
70
  */
228
71
  declare function getMimeType(path: string): string;
229
72
 
230
- export { type ClientError, type DropOptions, type DropReturn, type DropState, type DropStateValue, type DropStatus, FILE_STATUSES, type FileStatus, type FileWithPath, type ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize, getMimeType, isZipFile, normalizePath, stripCommonPrefix, traverseFileTree, useDrop };
73
+ export { ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize, getMimeType, isZipFile, normalizePath, stripCommonPrefix, traverseFileTree };
package/dist/index.js CHANGED
@@ -11700,7 +11700,7 @@ var require_mime_db = __commonJS({
11700
11700
  }
11701
11701
  });
11702
11702
 
11703
- // node_modules/.pnpm/@shipstatic+types@0.4.5/node_modules/@shipstatic/types/dist/index.js
11703
+ // node_modules/.pnpm/@shipstatic+types@0.4.7/node_modules/@shipstatic/types/dist/index.js
11704
11704
  var ErrorType;
11705
11705
  (function(ErrorType2) {
11706
11706
  ErrorType2["Validation"] = "validation_failed";
@@ -11914,7 +11914,15 @@ function useDrop(options) {
11914
11914
  const inputRef = useRef(null);
11915
11915
  const isProcessing = useMemo(() => state.value === "processing", [state.value]);
11916
11916
  const isDragging = useMemo(() => state.value === "dragging", [state.value]);
11917
+ const isInteractive = useMemo(
11918
+ () => state.value === "idle" || state.value === "dragging" || state.value === "ready",
11919
+ [state.value]
11920
+ );
11921
+ const hasError = useMemo(() => state.value === "error", [state.value]);
11917
11922
  const validFiles = useMemo(() => getValidFiles(state.files), [state.files]);
11923
+ const getFilesForUpload = useCallback(() => {
11924
+ return validFiles.map((f) => f.file);
11925
+ }, [validFiles]);
11918
11926
  const processFiles = useCallback(async (newFiles) => {
11919
11927
  if (isProcessingRef.current) {
11920
11928
  console.warn("File processing already in progress. Ignoring duplicate call.");
@@ -12025,18 +12033,10 @@ function useDrop(options) {
12025
12033
  isProcessingRef.current = false;
12026
12034
  }
12027
12035
  }, [ship, onValidationError, onFilesReady, stripPrefix]);
12028
- const clearAll = useCallback(() => {
12036
+ const reset = useCallback(() => {
12029
12037
  setState(initialState);
12030
12038
  isProcessingRef.current = false;
12031
12039
  }, []);
12032
- const updateFileStatus = useCallback((fileId, fileState) => {
12033
- setState((prev) => ({
12034
- ...prev,
12035
- files: prev.files.map(
12036
- (file) => file.id === fileId ? { ...file, ...fileState } : file
12037
- )
12038
- }));
12039
- }, []);
12040
12040
  const handleDragOver = useCallback((e) => {
12041
12041
  e.preventDefault();
12042
12042
  setState((prev) => {
@@ -12119,12 +12119,15 @@ function useDrop(options) {
12119
12119
  const open = useCallback(() => {
12120
12120
  inputRef.current?.click();
12121
12121
  }, []);
12122
- const getDropzoneProps = useCallback(() => ({
12123
- onDragOver: handleDragOver,
12124
- onDragLeave: handleDragLeave,
12125
- onDrop: handleDrop,
12126
- onClick: open
12127
- }), [handleDragOver, handleDragLeave, handleDrop, open]);
12122
+ const getDropzoneProps = useCallback((options2) => {
12123
+ const { clickable = true } = options2 ?? {};
12124
+ return {
12125
+ onDragOver: handleDragOver,
12126
+ onDragLeave: handleDragLeave,
12127
+ onDrop: handleDrop,
12128
+ ...clickable && { onClick: open }
12129
+ };
12130
+ }, [handleDragOver, handleDragLeave, handleDrop, open]);
12128
12131
  const getInputProps = useCallback(() => ({
12129
12132
  ref: inputRef,
12130
12133
  type: "file",
@@ -12134,11 +12137,12 @@ function useDrop(options) {
12134
12137
  onChange: handleInputChange
12135
12138
  }), [handleInputChange]);
12136
12139
  return {
12137
- // State machine
12138
12140
  // Convenience getters (computed from state)
12139
12141
  phase: state.value,
12140
12142
  isProcessing,
12141
12143
  isDragging,
12144
+ isInteractive,
12145
+ hasError,
12142
12146
  files: state.files,
12143
12147
  sourceName: state.sourceName,
12144
12148
  status: state.status,
@@ -12148,10 +12152,10 @@ function useDrop(options) {
12148
12152
  // Actions
12149
12153
  open,
12150
12154
  processFiles,
12151
- clearAll,
12155
+ reset,
12152
12156
  // Helpers
12153
12157
  validFiles,
12154
- updateFileStatus
12158
+ getFilesForUpload
12155
12159
  };
12156
12160
  }
12157
12161
  /*! Bundled license information: