@expresscsv/react 0.1.4 → 0.1.5

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 CHANGED
@@ -1,6 +1,9 @@
1
- # ExpressCSV React SDK
1
+ # @expresscsv/react
2
2
 
3
- A React component wrapper for the ExpressCSV SDK that provides a simple, declarative way to integrate CSV import functionality into your React applications.
3
+ [![npm version](https://img.shields.io/npm/v/@expresscsv/react.svg)](https://www.npmjs.com/package/@expresscsv/react)
4
+ [![license](https://img.shields.io/npm/l/@expresscsv/react.svg)](https://github.com/nicholasgriffintn/expresscsv/blob/main/LICENSE)
5
+
6
+ React hook for embedding the [ExpressCSV](https://expresscsv.com) CSV import widget. Wraps [`@expresscsv/sdk`](https://www.npmjs.com/package/@expresscsv/sdk) with automatic lifecycle management and reactive state.
4
7
 
5
8
  ## Installation
6
9
 
@@ -15,47 +18,45 @@ npm install @expresscsv/react
15
18
  yarn add @expresscsv/react
16
19
  ```
17
20
 
18
- ## Usage
19
-
20
- The React SDK provides a `useExpressCSV` hook for easy integration into your React components.
21
-
22
- ### Basic Usage
21
+ > **Peer dependency:** React 18+
23
22
 
24
- The React SDK provides a `useExpressCSV` hook for easy integration:
23
+ ## Quick Start
25
24
 
26
25
  ```tsx
27
- import { useExpressCSV, x, type Infer } from '@expresscsv/react';
26
+ import { useExpressCSV, x } from "@expresscsv/react";
28
27
 
29
28
  const schema = x.row({
30
- name: x.string().label('Full Name'),
31
- email: x.string().email().label('Email Address'),
32
- age: x.number().label('Age').min(18),
29
+ name: x.string().label("Full Name"),
30
+ email: x.string().email().label("Email Address"),
31
+ age: x.number().label("Age").min(18),
33
32
  });
34
33
 
35
34
  function App() {
36
- const { open, isOpen, widgetState } = useExpressCSV({
35
+ const { open, isOpen } = useExpressCSV({
37
36
  schema,
38
- title: "Import Users",
37
+ publishableKey: "your-publishable-key",
39
38
  importIdentifier: "user-import",
39
+ title: "Import Users",
40
40
  });
41
41
 
42
42
  const handleImport = () => {
43
43
  open({
44
- chunkSize: 100,
44
+ chunkSize: 500,
45
45
  onData: async (chunk, next) => {
46
- console.log(`Processing chunk ${chunk.currentChunkIndex + 1}/${chunk.totalChunks}`);
47
- console.log('CSV data:', chunk.records);
48
- // Process your validated data here
46
+ console.log(
47
+ `Chunk ${chunk.currentChunkIndex + 1}/${chunk.totalChunks}`
48
+ );
49
+ console.log("Records:", chunk.records);
49
50
  next();
50
51
  },
51
52
  onComplete: () => {
52
- console.log('All chunks processed');
53
+ console.log("All chunks processed");
53
54
  },
54
55
  onCancel: () => {
55
- console.log('User cancelled import');
56
+ console.log("User cancelled");
56
57
  },
57
58
  onError: (error) => {
58
- console.error('Import error:', error);
59
+ console.error("Import error:", error);
59
60
  },
60
61
  });
61
62
  };
@@ -68,226 +69,166 @@ function App() {
68
69
  }
69
70
  ```
70
71
 
71
- ### Preload for Instant Display
72
+ Your `publishableKey` is available from the [ExpressCSV dashboard](https://expresscsv.com). Two key types are available: **production** keys for live usage, and **dev/testing** keys that provide unlimited test imports.
72
73
 
73
- By default, the widget preloads in the background for instant display. This provides the best user experience with minimal perceived loading time.
74
+ ## Preloading
74
75
 
75
- ```tsx
76
- import { useExpressCSV, x } from '@expresscsv/react';
76
+ By default the widget preloads in a hidden iframe so it appears instantly when `open()` is called:
77
77
 
78
- const schema = x.row({
79
- name: x.string().label('Full Name'),
80
- email: x.string().email().label('Email Address'),
78
+ ```tsx
79
+ const { open } = useExpressCSV({
80
+ schema,
81
+ publishableKey: "your-publishable-key",
82
+ importIdentifier: "user-import",
81
83
  });
82
84
 
83
- function App() {
84
- // Preload is enabled by default
85
- const { open } = useExpressCSV({
86
- schema,
87
- title: "Import Users",
88
- importIdentifier: "user-import",
85
+ // Widget displays instantly
86
+ const handleImport = () => {
87
+ open({
88
+ onData: (chunk, next) => {
89
+ console.log("Records:", chunk.records);
90
+ next();
91
+ },
89
92
  });
90
-
91
- const handleImport = () => {
92
- open({
93
- onData: async (chunk, next) => {
94
- console.log('CSV data:', chunk.records);
95
- next();
96
- },
97
- });
98
- };
99
-
100
- return (
101
- <button onClick={handleImport}>
102
- Import CSV
103
- </button>
104
- );
105
- }
93
+ };
106
94
  ```
107
95
 
108
- To disable preload for specific use cases (not recommended for most scenarios):
96
+ To disable preloading:
109
97
 
110
98
  ```tsx
111
99
  const { open } = useExpressCSV({
112
100
  schema,
113
- title: "Import Users",
101
+ publishableKey: "your-publishable-key",
114
102
  importIdentifier: "user-import",
115
- preload: false, // Disable preload
103
+ preload: false,
116
104
  });
117
105
  ```
118
106
 
119
- ### Webhook Delivery
107
+ ## Webhook Delivery
120
108
 
121
- You can deliver CSV data to a webhook endpoint instead of (or in addition to) using local callbacks. The backend will handle retries, exponential backoff, and deliver data in chunks:
109
+ Deliver data to a server endpoint instead of (or in addition to) processing locally:
122
110
 
123
111
  ```tsx
124
- import { useExpressCSV, x, type Infer, type WebhookConfig } from '@expresscsv/react';
112
+ import { useExpressCSV, x } from "@expresscsv/react";
125
113
 
126
114
  const schema = x.row({
127
- name: x.string().label('Full Name'),
128
- email: x.string().email().label('Email Address'),
115
+ name: x.string().label("Full Name"),
116
+ email: x.string().email().label("Email Address"),
129
117
  });
130
118
 
131
119
  function App() {
132
120
  const { open } = useExpressCSV({
133
121
  schema,
134
- title: "Import Users",
122
+ publishableKey: "your-publishable-key",
135
123
  importIdentifier: "user-import",
124
+ title: "Import Users",
136
125
  });
137
126
 
138
127
  const handleImport = () => {
139
128
  open({
140
- chunkSize: 500, // Optional: chunk size for webhook delivery (default: 1000)
141
129
  webhook: {
142
- url: 'https://api.example.com/webhooks/csv-import',
143
- method: 'POST',
130
+ url: "https://api.example.com/webhooks/csv-import",
131
+ method: "POST",
144
132
  headers: {
145
- 'Authorization': 'Bearer your-api-token',
146
- 'X-Custom-Header': 'custom-value',
133
+ Authorization: "Bearer your-api-token",
147
134
  },
148
135
  metadata: {
149
- // Optional: arbitrary metadata to include in webhook payload
150
- source: 'react-app',
151
- userId: 'user-123',
136
+ source: "react-app",
137
+ userId: "user-123",
152
138
  },
153
139
  },
154
140
  onComplete: () => {
155
- console.log('Webhook delivery initiated');
141
+ console.log("Webhook delivery initiated");
156
142
  },
157
143
  onError: (error) => {
158
- console.error('Webhook delivery error:', error);
144
+ console.error("Delivery error:", error);
159
145
  },
160
146
  });
161
147
  };
162
148
 
163
- return (
164
- <button onClick={handleImport}>
165
- Import CSV via Webhook
166
- </button>
167
- );
149
+ return <button onClick={handleImport}>Import CSV via Webhook</button>;
168
150
  }
169
151
  ```
170
152
 
171
153
  ### Combined Local Callback and Webhook
172
154
 
173
- You can use both `onData` callback and webhook delivery simultaneously:
174
-
175
155
  ```tsx
176
- import { useExpressCSV, x, type Infer } from '@expresscsv/react';
177
-
178
- const schema = x.row({
179
- name: x.string().label('Full Name'),
180
- email: x.string().email().label('Email Address'),
156
+ open({
157
+ chunkSize: 500,
158
+ onData: async (chunk, next) => {
159
+ await saveToLocalDatabase(chunk.records);
160
+ next();
161
+ },
162
+ webhook: {
163
+ url: "https://api.example.com/webhooks/csv-import",
164
+ headers: { Authorization: "Bearer your-api-token" },
165
+ },
166
+ onComplete: () => {
167
+ console.log("Local processing and webhook delivery complete");
168
+ },
181
169
  });
182
-
183
- function App() {
184
- const { open } = useExpressCSV({
185
- schema,
186
- title: "Import Users",
187
- importIdentifier: "user-import",
188
- });
189
-
190
- const handleImport = () => {
191
- open({
192
- chunkSize: 100,
193
- // Process locally
194
- onData: async (chunk, next) => {
195
- console.log(`Processing chunk ${chunk.currentChunkIndex + 1}/${chunk.totalChunks}`);
196
- // Your local processing logic
197
- await processChunkLocally(chunk.records);
198
- next();
199
- },
200
- // Also deliver to webhook
201
- webhook: {
202
- url: 'https://api.example.com/webhooks/csv-import',
203
- headers: {
204
- 'Authorization': 'Bearer your-api-token',
205
- },
206
- },
207
- onComplete: () => {
208
- console.log('All chunks processed and webhook delivery initiated');
209
- },
210
- });
211
- };
212
-
213
- return (
214
- <button onClick={handleImport}>
215
- Import CSV
216
- </button>
217
- );
218
- }
219
170
  ```
220
171
 
221
- ### Advanced Example with Error Handling
172
+ ## Advanced Example
222
173
 
223
174
  ```tsx
224
- import { useExpressCSV, x, type Infer } from '@expresscsv/react';
225
- import { useState } from 'react';
175
+ import { useExpressCSV, x, type Infer } from "@expresscsv/react";
176
+ import { useState } from "react";
226
177
 
227
178
  const candidateSchema = x.row({
228
- firstName: x.string().label('First Name'),
229
- lastName: x.string().label('Last Name'),
230
- email: x.string().email().label('Email'),
231
- experienceLevel: x.select([
232
- { label: 'Entry Level', value: 'entry' },
233
- { label: 'Mid Level', value: 'mid' },
234
- { label: 'Senior Level', value: 'senior' },
235
- ]).label('Experience Level'),
236
- salary: x.number().currency('USD').min(30000).label('Expected Salary'),
179
+ firstName: x.string().label("First Name"),
180
+ lastName: x.string().label("Last Name"),
181
+ email: x.string().email().label("Email"),
182
+ level: x
183
+ .select([
184
+ { label: "Entry Level", value: "entry" },
185
+ { label: "Mid Level", value: "mid" },
186
+ { label: "Senior Level", value: "senior" },
187
+ ])
188
+ .label("Experience Level"),
189
+ salary: x.number().currency("USD").min(30000).label("Expected Salary"),
237
190
  });
238
191
 
239
192
  function CandidateImporter() {
240
- const [isLoading, setIsLoading] = useState(false);
241
- const [error, setError] = useState<string | null>(null);
193
+ const [status, setStatus] = useState<string | null>(null);
242
194
 
243
- const { open } = useExpressCSV({
195
+ const { open, isOpen } = useExpressCSV({
244
196
  schema: candidateSchema,
245
- title: "Import Candidates",
197
+ publishableKey: "your-publishable-key",
246
198
  importIdentifier: "candidate-import",
247
- developerMode: process.env.NODE_ENV === 'development',
248
- debug: process.env.NODE_ENV === 'development',
199
+ title: "Import Candidates",
200
+ developerMode: process.env.NODE_ENV === "development",
249
201
  });
250
202
 
251
203
  const handleImport = () => {
252
- setIsLoading(true);
253
- setError(null);
204
+ setStatus(null);
254
205
 
255
206
  open({
256
207
  onData: async (chunk, next) => {
257
- try {
258
- // Process the candidates chunk
259
- await importCandidates(chunk.records);
260
- next();
261
- } catch (err) {
262
- setError('Failed to import candidates. Please try again.');
263
- throw err;
264
- }
208
+ setStatus(
209
+ `Processing chunk ${chunk.currentChunkIndex + 1}/${chunk.totalChunks}...`
210
+ );
211
+ await importCandidates(chunk.records);
212
+ next();
265
213
  },
266
214
  onComplete: () => {
267
- setIsLoading(false);
268
- alert('Successfully imported all candidates!');
215
+ setStatus("Import complete!");
269
216
  },
270
217
  onError: (error) => {
271
- setIsLoading(false);
272
- setError(`Import failed: ${error.message}`);
218
+ setStatus(`Error: ${error.message}`);
273
219
  },
274
220
  onCancel: () => {
275
- setIsLoading(false);
221
+ setStatus(null);
276
222
  },
277
223
  });
278
224
  };
279
225
 
280
226
  return (
281
227
  <div>
282
- {error && <div className="error">{error}</div>}
283
-
284
- <button
285
- onClick={handleImport}
286
- disabled={isLoading}
287
- className="import-button"
288
- >
289
- {isLoading ? 'Processing...' : 'Import Candidates'}
228
+ <button onClick={handleImport} disabled={isOpen}>
229
+ {isOpen ? "Importing..." : "Import Candidates"}
290
230
  </button>
231
+ {status && <p>{status}</p>}
291
232
  </div>
292
233
  );
293
234
  }
@@ -295,126 +236,134 @@ function CandidateImporter() {
295
236
 
296
237
  ## API Reference
297
238
 
298
- ### useExpressCSV Hook
239
+ ### `useExpressCSV(options)`
299
240
 
300
- A custom hook that provides access to the CSV importer functionality.
301
-
302
- #### Parameters
303
-
304
- ```tsx
305
- interface UseExpressCSVOptions<TSchema> {
306
- schema: TSchema;
307
- title?: string;
308
- importIdentifier: string;
309
- publishableKey: string;
310
- debug?: boolean;
311
- developerMode?: boolean;
312
- preload?: boolean; // Defaults to true
313
- theme?: ECSVTheme;
314
- colorMode?: ColorModeConfig;
315
- customCSS?: string;
316
- fonts?: Record<string, ECSVFontSource>;
317
- stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
318
- }
319
- ```
320
-
321
- #### Returns
322
-
323
- ```tsx
324
- {
241
+ ```typescript
242
+ function useExpressCSV<TSchema>(
243
+ options: UseExpressCSVOptions<TSchema>
244
+ ): {
325
245
  open: (options: OpenOptions<Infer<TSchema>>) => void;
326
246
  widgetState: WidgetState;
327
247
  isInitialising: boolean;
328
248
  isOpen: boolean;
329
- }
249
+ };
330
250
  ```
331
251
 
332
- ### OpenOptions
333
-
334
- Options passed to the `open` method:
335
-
336
- ```tsx
337
- interface OpenOptions<T> {
338
- // At least one of onData or webhook must be provided
339
- onData?: (chunk: RecordsChunk<T>, next: () => void) => void | Promise<void>;
340
- webhook?: WebhookConfig;
341
-
342
- // Optional configuration
343
- chunkSize?: number; // Default: 1000
344
- onComplete?: () => void;
345
- onCancel?: () => void;
346
- onError?: (error: Error) => void;
252
+ #### Options
253
+
254
+ | Option | Type | Required | Default | Description |
255
+ |---|---|---|---|---|
256
+ | `schema` | Schema | Yes | - | Schema definition created with `x.row()` |
257
+ | `publishableKey` | `string` | Yes | - | Your publishable key from the [dashboard](https://expresscsv.com) |
258
+ | `importIdentifier` | `string` | Yes | - | Unique identifier for this import type |
259
+ | `title` | `string` | No | - | Title shown in the widget header |
260
+ | `preload` | `boolean` | No | `true` | Preload widget for instant display |
261
+ | `debug` | `boolean` | No | `false` | Enable debug logging |
262
+ | `developerMode` | `boolean` | No | `false` | Enable developer mode features |
263
+ | `theme` | `ECSVTheme` | No | - | Custom theme configuration |
264
+ | `colorMode` | `ColorModeConfig` | No | - | Light/dark mode settings |
265
+ | `customCSS` | `string` | No | - | Custom CSS to inject into the widget |
266
+ | `fonts` | `Record<string, ECSVFontSource>` | No | - | Custom font sources |
267
+ | `stepDisplay` | `'progressBar' \| 'segmented' \| 'numbered'` | No | `'progressBar'` | Step indicator style |
268
+ | `previewSchemaBeforeUpload` | `boolean` | No | `true` | Show schema preview before upload |
269
+ | `templateDownload` | `TemplateDownloadConfig` | No | - | Template download configuration |
270
+ | `saveSession` | `boolean` | No | - | Persist session state |
271
+ | `locale` | `DeepPartial<ExpressCSVLocaleInput>` | No | - | Localization overrides |
272
+
273
+ #### Return Value
274
+
275
+ | Property | Type | Description |
276
+ |---|---|---|
277
+ | `open` | `(options: OpenOptions) => void` | Opens the widget. Requires at least one of `onData` or `webhook`. |
278
+ | `widgetState` | `WidgetState` | Current widget state (reactive) |
279
+ | `isInitialising` | `boolean` | `true` while the widget is initializing or opening |
280
+ | `isOpen` | `boolean` | `true` while the widget is open |
281
+
282
+ ### `OpenOptions<T>`
283
+
284
+ Options passed to `open()`. At least one of `onData` or `webhook` must be provided.
285
+
286
+ | Option | Type | Required | Description |
287
+ |---|---|---|---|
288
+ | `onData` | `(chunk: RecordsChunk<T>, next: () => void) => void` | * | Callback for each chunk. Call `next()` to continue. |
289
+ | `webhook` | `WebhookConfig` | * | Webhook endpoint for server-side delivery |
290
+ | `chunkSize` | `number` | No | Records per chunk (default: 1000) |
291
+ | `onComplete` | `() => void` | No | Called when all chunks have been processed |
292
+ | `onCancel` | `() => void` | No | Called when the user cancels the import |
293
+ | `onError` | `(error: Error) => void` | No | Called when an error occurs |
294
+ | `onWidgetOpen` | `() => void` | No | Called when the widget opens |
295
+ | `onWidgetClose` | `(reason: string) => void` | No | Called when the widget closes |
296
+ | `onStepChange` | `(stepId, previousStepId?) => void` | No | Called when the wizard step changes |
297
+
298
+ \* At least one of `onData` or `webhook` is required.
299
+
300
+ ### `RecordsChunk<T>`
301
+
302
+ ```typescript
303
+ interface RecordsChunk<T> {
304
+ records: T[];
305
+ totalChunks: number;
306
+ currentChunkIndex: number;
307
+ totalRecords: number;
347
308
  }
348
309
  ```
349
310
 
350
- ### WebhookConfig
351
-
352
- Configuration for webhook delivery:
311
+ ### `WebhookConfig`
353
312
 
354
- ```tsx
313
+ ```typescript
355
314
  interface WebhookConfig {
356
- url: string; // Required: Webhook endpoint URL
357
- headers?: Record<string, string>; // Optional HTTP headers
358
- method?: 'POST' | 'PUT' | 'PATCH'; // Default: 'POST'
359
- timeout?: number; // Request timeout in milliseconds (default: 30000)
360
- retries?: number; // Number of retry attempts (default: 0)
361
- metadata?: Record<string, unknown>; // Optional metadata to include in webhook payload
315
+ url: string;
316
+ headers?: Record<string, string>;
317
+ method?: "POST" | "PUT" | "PATCH";
318
+ timeout?: number;
319
+ retries?: number;
320
+ metadata?: Record<string, unknown>;
362
321
  }
363
322
  ```
364
323
 
365
- **Note:** The `chunkSize` option in `OpenOptions` controls the chunk size for both `onData` callbacks and webhook delivery. The backend will deliver webhooks in chunks of this size (or default 1000 if not specified).
366
-
367
324
  ### Schema Builder
368
325
 
369
- The schema builder (`x`) provides a fluent API for defining field validation:
326
+ The `x` schema builder is re-exported from `@expresscsv/sdk`. See the [SDK README](https://www.npmjs.com/package/@expresscsv/sdk#schema-builder) for the full field type and modifier reference.
370
327
 
371
328
  ```tsx
329
+ import { x } from "@expresscsv/react";
330
+
372
331
  const schema = x.row({
373
- // String fields
374
- name: x.string().label('Name').minLength(2).maxLength(50),
375
-
376
- // Email validation
377
- email: x.string().email().label('Email Address'),
378
-
379
- // Number fields with constraints
380
- age: x.number().label('Age').min(18).max(100),
381
-
382
- // Currency fields
383
- salary: x.number().currency('USD').min(30000),
384
-
385
- // Select dropdowns
332
+ name: x.string().label("Name").min(2).max(100),
333
+ email: x.string().email().label("Email"),
334
+ age: x.number().label("Age").min(0).integer(),
386
335
  role: x.select([
387
- { label: 'Admin', value: 'admin' },
388
- { label: 'User', value: 'user' },
389
- ]).label('Role'),
390
-
391
- // Date fields
392
- startDate: x.date().label('Start Date'),
393
-
394
- // Boolean fields
395
- isActive: x.boolean().label('Active Status'),
336
+ { label: "Admin", value: "admin" },
337
+ { label: "User", value: "user" },
338
+ ]).label("Role"),
339
+ startDate: x.date().label("Start Date"),
340
+ isActive: x.boolean().label("Active"),
396
341
  });
397
342
  ```
398
343
 
399
- ## TypeScript Support
344
+ ## TypeScript
400
345
 
401
- The component provides full TypeScript support with automatic type inference:
346
+ Full type inference from your schema is built in:
402
347
 
403
348
  ```tsx
349
+ import { x, type Infer } from "@expresscsv/react";
350
+
404
351
  const schema = x.row({
405
352
  name: x.string(),
406
353
  age: x.number(),
407
354
  });
408
355
 
409
- // results is automatically typed as { name: string; age: number }[]
410
- const handleResults = (results: Infer<typeof schema>[]) => {
411
- results.forEach(row => {
412
- console.log(row.name); // string
413
- console.log(row.age); // number
414
- });
415
- };
356
+ type Row = Infer<typeof schema>;
357
+ // { name: string; age: number }
416
358
  ```
417
359
 
360
+ The `onData` callback receives `RecordsChunk<Row>` automatically -- no manual type annotations needed.
361
+
362
+ ## Resources
363
+
364
+ - [ExpressCSV Dashboard](https://expresscsv.com) -- manage your imports and API keys
365
+ - [`@expresscsv/sdk`](https://www.npmjs.com/package/@expresscsv/sdk) -- vanilla JS SDK (no React dependency)
366
+
418
367
  ## License
419
368
 
420
- ISC
369
+ [MIT](./LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expresscsv/react",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "React component wrapper for ExpressCSV SDK",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.mts",
@@ -1,27 +0,0 @@
1
- import type { DeepPartial, ExpressCSVLocaleInput, TemplateDownloadConfig } from '@expresscsv/core';
2
- import { type ColorModeConfig, type ECSVFontSource, type ECSVTheme, type ExBaseDef, type ExType, type Infer, type OpenOptions, WidgetState } from '@expresscsv/sdk';
3
- export type { ColorModeConfig, ColorModePref, ECSVTheme, TailwindThemeVars, } from '@expresscsv/sdk';
4
- export interface UseExpressCSVOptions<TSchema extends ExType<unknown, ExBaseDef, unknown>> {
5
- schema: TSchema;
6
- title?: string;
7
- importIdentifier: string;
8
- publishableKey: string;
9
- debug?: boolean;
10
- developerMode?: boolean;
11
- preload?: boolean;
12
- theme?: ECSVTheme;
13
- colorMode?: ColorModeConfig;
14
- customCSS?: string;
15
- fonts?: Record<string, ECSVFontSource>;
16
- stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
17
- previewSchemaBeforeUpload?: boolean;
18
- templateDownload?: TemplateDownloadConfig;
19
- saveSession?: boolean;
20
- locale?: DeepPartial<ExpressCSVLocaleInput>;
21
- }
22
- export declare function useExpressCSV<TSchema extends ExType<unknown, ExBaseDef, unknown>>({ schema, title, importIdentifier, publishableKey, debug, developerMode, preload, theme, colorMode, customCSS, fonts, stepDisplay, previewSchemaBeforeUpload, templateDownload, saveSession, locale, }: UseExpressCSVOptions<TSchema>): {
23
- open: (options: OpenOptions<Infer<TSchema>>) => void;
24
- widgetState: WidgetState;
25
- isInitialising: boolean;
26
- isOpen: boolean;
27
- };
@@ -1,4 +0,0 @@
1
- export { useExpressCSV, type UseExpressCSVOptions, } from './CSVImporter';
2
- export { x, WidgetState, WidgetMode, ImportCancelledError, } from '@expresscsv/sdk';
3
- export type { Infer, ECSVFontSource, ECSVTheme, TailwindThemeVars, ColorModeConfig, ColorModePref, ExpressCSVStep, RecordsChunk, OpenOptions, WebhookConfig, DeliveryOptions, } from '@expresscsv/sdk';
4
- export type { TemplateDownloadConfig, TemplateDownloadFormat, ExpressCSVLocaleInput, DeepPartial, } from '@expresscsv/core';