@expresscsv/react 0.1.18 → 0.1.19

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
@@ -106,6 +106,40 @@ const { open } = useExpressCSV({
106
106
  });
107
107
  ```
108
108
 
109
+ ## Template Downloads
110
+
111
+ Generated templates can include example rows that match your schema.
112
+
113
+ ```tsx
114
+ import { useExpressCSV, x, type Infer } from "@expresscsv/react";
115
+
116
+ const candidateSchema = x.row({
117
+ firstName: x.string().label("First Name"),
118
+ email: x.string().email().label("Email"),
119
+ role: x.select([
120
+ { label: "Admin", value: "admin" },
121
+ { label: "Editor", value: "editor" },
122
+ ]).label("Role"),
123
+ });
124
+
125
+ const { open } = useExpressCSV({
126
+ schema: candidateSchema,
127
+ publishableKey: "your-publishable-key",
128
+ importIdentifier: "candidate-import",
129
+ templateDownload: {
130
+ source: "generate",
131
+ formats: ["csv", "xlsx"],
132
+ exampleRows: () => [
133
+ {
134
+ firstName: "Alice",
135
+ email: "alice@example.com",
136
+ role: "admin",
137
+ },
138
+ ],
139
+ },
140
+ });
141
+ ```
142
+
109
143
  ## Theming and Styling
110
144
 
111
145
  Customize the widget's appearance with the `theme`, `colorMode`, `customCSS`, and `fonts` options.
@@ -530,7 +564,7 @@ function useExpressCSV<TSchema>(
530
564
  | `fonts` | `Record<string, ECSVFontSource>` | No | - | Custom font sources |
531
565
  | `stepDisplay` | `'progressBar' \| 'segmented' \| 'numbered'` | No | `'progressBar'` | Step indicator style |
532
566
  | `previewSchemaBeforeUpload` | `boolean` | No | `true` | Show schema preview before upload |
533
- | `templateDownload` | `TemplateDownloadConfig` | No | - | Template download configuration |
567
+ | `templateDownload` | `TemplateDownloadOptions<TSchema>` | No | - | Template download configuration with optional schema-typed example rows |
534
568
  | `saveSession` | `boolean` | No | - | Persist session state |
535
569
  | `locale` | `DeepPartial<ExpressCSVLocaleInput>` | No | - | Localization overrides |
536
570
 
@@ -648,7 +682,7 @@ const schema = x.row({
648
682
  });
649
683
  ```
650
684
 
651
- `x.dynamicRow(...)` lets you build the row at runtime, which is useful when the schema depends on account data, user preferences, or enabled custom fields.
685
+ `x.row(...)` also works for runtime-built schemas, which is useful when the shape depends on account data, user preferences, or enabled custom fields.
652
686
 
653
687
  ```tsx
654
688
  import { x } from "@expresscsv/react";
@@ -658,7 +692,7 @@ function buildCustomerSchema(options: {
658
692
  collectHealthScore: boolean;
659
693
  collectSegment: boolean;
660
694
  }) {
661
- return x.dynamicRow({
695
+ return x.row({
662
696
  email: x.string().email().label("Email"),
663
697
  companyName: x.string().label("Company Name"),
664
698
  ...(options.collectCrmId ? { crmId: x.string().label("CRM ID") } : {}),
@@ -686,6 +720,8 @@ const schema = buildCustomerSchema({
686
720
  });
687
721
  ```
688
722
 
723
+ Dynamic schema assembly preserves the same runtime parsing behavior, but it can widen `Infer<typeof schema>` because the exact keys are no longer fully known to TypeScript. Use it intentionally.
724
+
689
725
  #### Common Modifiers
690
726
 
691
727
  All field types support:
package/dist/index.d.cts CHANGED
@@ -3015,16 +3015,14 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
3015
3015
  * Factory method to create an ExRow validator for a row of data
3016
3016
  *
3017
3017
  * @param shape - Object defining the structure of fields in the row
3018
+ *
3019
+ * Object literals preserve exact key inference. If callers build the shape
3020
+ * through a widened variable or conditional assembly, TypeScript may widen
3021
+ * the resulting row type as well.
3022
+ *
3018
3023
  * @returns A new ExRow instance
3019
3024
  */
3020
3025
  static create<T extends ExRowShape>(shape: T): ExRow<T>;
3021
- /**
3022
- * Factory method for runtime-built row shapes.
3023
- *
3024
- * This intentionally widens the returned type to ExRow<ExRowShape> so callers
3025
- * can assemble fields conditionally without relying on exact key inference.
3026
- */
3027
- static createDynamic(shape: ExRowShape): ExRow<ExRowShape>;
3028
3026
  /**
3029
3027
  * Specifies columns that can be null/optional with conditional logic
3030
3028
  *
@@ -3702,19 +3700,29 @@ export declare interface TailwindThemeVars {
3702
3700
 
3703
3701
  /**
3704
3702
  * Configuration for template download in the upload step.
3705
- * When `source` is `"generate"`, a header-only template file is created
3706
- * client-side from the schema column names.
3703
+ * When `source` is `"generate"`, a template file is created client-side
3704
+ * from the schema column names and optional example rows.
3707
3705
  */
3708
3706
  export declare interface TemplateDownloadConfig {
3709
3707
  source: 'generate';
3710
3708
  formats?: TemplateDownloadFormat[];
3709
+ exampleRows?: TemplateDownloadExampleRow[];
3711
3710
  }
3712
3711
 
3712
+ /**
3713
+ * A serializable example row used to populate generated templates.
3714
+ */
3715
+ export declare type TemplateDownloadExampleRow = Record<string, unknown>;
3716
+
3713
3717
  /**
3714
3718
  * Template download format
3715
3719
  */
3716
3720
  export declare type TemplateDownloadFormat = 'csv' | 'xlsx';
3717
3721
 
3722
+ export declare type TemplateDownloadOptions<TSchema extends ExType<unknown, ExBaseDef, unknown>> = Omit<TemplateDownloadConfig, 'exampleRows'> & {
3723
+ exampleRows?: Infer<TSchema>[] | (() => Infer<TSchema>[]);
3724
+ };
3725
+
3718
3726
  /**
3719
3727
  * A branded string type for locale entries that require interpolation via `{variable}` syntax.
3720
3728
  * Widget code cannot render a `TemplateString` directly in JSX — it must go through the `t()` function.
@@ -3761,7 +3769,7 @@ export declare interface UseExpressCSVOptions<TSchema extends ExType<unknown, Ex
3761
3769
  fonts?: Record<string, ECSVFontSource>;
3762
3770
  stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
3763
3771
  previewSchemaBeforeUpload?: boolean;
3764
- templateDownload?: TemplateDownloadConfig;
3772
+ templateDownload?: TemplateDownloadOptions<TSchema>;
3765
3773
  saveSession?: boolean;
3766
3774
  locale?: DeepPartial<ExpressCSVLocaleInput>;
3767
3775
  disableStatusStep?: boolean;
@@ -3831,7 +3839,6 @@ export declare const x: {
3831
3839
  time: typeof ExTime.create;
3832
3840
  datetime: typeof ExDatetime.create;
3833
3841
  row: typeof ExRow.create;
3834
- dynamicRow: typeof ExRow.createDynamic;
3835
3842
  select: typeof ExSelect.create;
3836
3843
  multiselect: typeof ExMultiselect.create;
3837
3844
  infer: <T extends ExType<unknown, ExBaseDef, unknown>>(_schema: T) => Infer<T>;
package/dist/index.d.mts CHANGED
@@ -3015,16 +3015,14 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
3015
3015
  * Factory method to create an ExRow validator for a row of data
3016
3016
  *
3017
3017
  * @param shape - Object defining the structure of fields in the row
3018
+ *
3019
+ * Object literals preserve exact key inference. If callers build the shape
3020
+ * through a widened variable or conditional assembly, TypeScript may widen
3021
+ * the resulting row type as well.
3022
+ *
3018
3023
  * @returns A new ExRow instance
3019
3024
  */
3020
3025
  static create<T extends ExRowShape>(shape: T): ExRow<T>;
3021
- /**
3022
- * Factory method for runtime-built row shapes.
3023
- *
3024
- * This intentionally widens the returned type to ExRow<ExRowShape> so callers
3025
- * can assemble fields conditionally without relying on exact key inference.
3026
- */
3027
- static createDynamic(shape: ExRowShape): ExRow<ExRowShape>;
3028
3026
  /**
3029
3027
  * Specifies columns that can be null/optional with conditional logic
3030
3028
  *
@@ -3702,19 +3700,29 @@ export declare interface TailwindThemeVars {
3702
3700
 
3703
3701
  /**
3704
3702
  * Configuration for template download in the upload step.
3705
- * When `source` is `"generate"`, a header-only template file is created
3706
- * client-side from the schema column names.
3703
+ * When `source` is `"generate"`, a template file is created client-side
3704
+ * from the schema column names and optional example rows.
3707
3705
  */
3708
3706
  export declare interface TemplateDownloadConfig {
3709
3707
  source: 'generate';
3710
3708
  formats?: TemplateDownloadFormat[];
3709
+ exampleRows?: TemplateDownloadExampleRow[];
3711
3710
  }
3712
3711
 
3712
+ /**
3713
+ * A serializable example row used to populate generated templates.
3714
+ */
3715
+ export declare type TemplateDownloadExampleRow = Record<string, unknown>;
3716
+
3713
3717
  /**
3714
3718
  * Template download format
3715
3719
  */
3716
3720
  export declare type TemplateDownloadFormat = 'csv' | 'xlsx';
3717
3721
 
3722
+ export declare type TemplateDownloadOptions<TSchema extends ExType<unknown, ExBaseDef, unknown>> = Omit<TemplateDownloadConfig, 'exampleRows'> & {
3723
+ exampleRows?: Infer<TSchema>[] | (() => Infer<TSchema>[]);
3724
+ };
3725
+
3718
3726
  /**
3719
3727
  * A branded string type for locale entries that require interpolation via `{variable}` syntax.
3720
3728
  * Widget code cannot render a `TemplateString` directly in JSX — it must go through the `t()` function.
@@ -3761,7 +3769,7 @@ export declare interface UseExpressCSVOptions<TSchema extends ExType<unknown, Ex
3761
3769
  fonts?: Record<string, ECSVFontSource>;
3762
3770
  stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
3763
3771
  previewSchemaBeforeUpload?: boolean;
3764
- templateDownload?: TemplateDownloadConfig;
3772
+ templateDownload?: TemplateDownloadOptions<TSchema>;
3765
3773
  saveSession?: boolean;
3766
3774
  locale?: DeepPartial<ExpressCSVLocaleInput>;
3767
3775
  disableStatusStep?: boolean;
@@ -3831,7 +3839,6 @@ export declare const x: {
3831
3839
  time: typeof ExTime.create;
3832
3840
  datetime: typeof ExDatetime.create;
3833
3841
  row: typeof ExRow.create;
3834
- dynamicRow: typeof ExRow.createDynamic;
3835
3842
  select: typeof ExSelect.create;
3836
3843
  multiselect: typeof ExMultiselect.create;
3837
3844
  infer: <T extends ExType<unknown, ExBaseDef, unknown>>(_schema: T) => Infer<T>;
package/dist/index.d.ts CHANGED
@@ -3015,16 +3015,14 @@ declare class ExRow<T extends ExRowShape> extends ExType<{
3015
3015
  * Factory method to create an ExRow validator for a row of data
3016
3016
  *
3017
3017
  * @param shape - Object defining the structure of fields in the row
3018
+ *
3019
+ * Object literals preserve exact key inference. If callers build the shape
3020
+ * through a widened variable or conditional assembly, TypeScript may widen
3021
+ * the resulting row type as well.
3022
+ *
3018
3023
  * @returns A new ExRow instance
3019
3024
  */
3020
3025
  static create<T extends ExRowShape>(shape: T): ExRow<T>;
3021
- /**
3022
- * Factory method for runtime-built row shapes.
3023
- *
3024
- * This intentionally widens the returned type to ExRow<ExRowShape> so callers
3025
- * can assemble fields conditionally without relying on exact key inference.
3026
- */
3027
- static createDynamic(shape: ExRowShape): ExRow<ExRowShape>;
3028
3026
  /**
3029
3027
  * Specifies columns that can be null/optional with conditional logic
3030
3028
  *
@@ -3702,19 +3700,29 @@ export declare interface TailwindThemeVars {
3702
3700
 
3703
3701
  /**
3704
3702
  * Configuration for template download in the upload step.
3705
- * When `source` is `"generate"`, a header-only template file is created
3706
- * client-side from the schema column names.
3703
+ * When `source` is `"generate"`, a template file is created client-side
3704
+ * from the schema column names and optional example rows.
3707
3705
  */
3708
3706
  export declare interface TemplateDownloadConfig {
3709
3707
  source: 'generate';
3710
3708
  formats?: TemplateDownloadFormat[];
3709
+ exampleRows?: TemplateDownloadExampleRow[];
3711
3710
  }
3712
3711
 
3712
+ /**
3713
+ * A serializable example row used to populate generated templates.
3714
+ */
3715
+ export declare type TemplateDownloadExampleRow = Record<string, unknown>;
3716
+
3713
3717
  /**
3714
3718
  * Template download format
3715
3719
  */
3716
3720
  export declare type TemplateDownloadFormat = 'csv' | 'xlsx';
3717
3721
 
3722
+ export declare type TemplateDownloadOptions<TSchema extends ExType<unknown, ExBaseDef, unknown>> = Omit<TemplateDownloadConfig, 'exampleRows'> & {
3723
+ exampleRows?: Infer<TSchema>[] | (() => Infer<TSchema>[]);
3724
+ };
3725
+
3718
3726
  /**
3719
3727
  * A branded string type for locale entries that require interpolation via `{variable}` syntax.
3720
3728
  * Widget code cannot render a `TemplateString` directly in JSX — it must go through the `t()` function.
@@ -3761,7 +3769,7 @@ export declare interface UseExpressCSVOptions<TSchema extends ExType<unknown, Ex
3761
3769
  fonts?: Record<string, ECSVFontSource>;
3762
3770
  stepDisplay?: 'progressBar' | 'segmented' | 'numbered';
3763
3771
  previewSchemaBeforeUpload?: boolean;
3764
- templateDownload?: TemplateDownloadConfig;
3772
+ templateDownload?: TemplateDownloadOptions<TSchema>;
3765
3773
  saveSession?: boolean;
3766
3774
  locale?: DeepPartial<ExpressCSVLocaleInput>;
3767
3775
  disableStatusStep?: boolean;
@@ -3831,7 +3839,6 @@ export declare const x: {
3831
3839
  time: typeof ExTime.create;
3832
3840
  datetime: typeof ExDatetime.create;
3833
3841
  row: typeof ExRow.create;
3834
- dynamicRow: typeof ExRow.createDynamic;
3835
3842
  select: typeof ExSelect.create;
3836
3843
  multiselect: typeof ExMultiselect.create;
3837
3844
  infer: <T extends ExType<unknown, ExBaseDef, unknown>>(_schema: T) => Infer<T>;