@douglasneuroinformatics/libui 3.8.2 → 3.8.4

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@douglasneuroinformatics/libui",
3
3
  "type": "module",
4
- "version": "3.8.2",
4
+ "version": "3.8.4",
5
5
  "packageManager": "pnpm@9.14.2",
6
6
  "description": "Generic UI components for DNP projects, built using React and Tailwind CSS",
7
7
  "author": "Joshua Unrau",
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { useEffect, useState } from 'react';
5
5
 
6
+ import { sleep } from '@douglasneuroinformatics/libjs';
6
7
  import type { FormFields } from '@douglasneuroinformatics/libui-form-types';
7
8
  import type FormTypes from '@douglasneuroinformatics/libui-form-types';
8
9
  import type { Meta, StoryObj } from '@storybook/react';
@@ -509,3 +510,24 @@ export const WithPreventReset: StoryObj<typeof Form<SimpleExampleFormSchemaType>
509
510
  validationSchema: $SimpleExampleFormData
510
511
  }
511
512
  };
513
+
514
+ export const WithSuspend: StoryObj<typeof Form<z.ZodType<FormTypes.Data>, { delay?: number }>> = {
515
+ args: {
516
+ content: {
517
+ delay: {
518
+ kind: 'number',
519
+ label: 'Delay (Seconds)',
520
+ variant: 'input'
521
+ }
522
+ },
523
+ suspendWhileSubmitting: true,
524
+ onSubmit: async (data) => {
525
+ await sleep(data.delay!);
526
+ // eslint-disable-next-line no-console
527
+ console.log(JSON.stringify(data, (_key, value) => (value instanceof Set ? [...value] : (value as unknown)), 2));
528
+ },
529
+ validationSchema: z.object({
530
+ delay: z.number().nonnegative().default(0)
531
+ })
532
+ }
533
+ };
@@ -101,22 +101,23 @@ const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TS
101
101
  };
102
102
 
103
103
  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
104
- const minSubmitTime = new Promise<void>((resolve) =>
105
- suspendWhileSubmitting ? setTimeout(resolve, 500) : resolve()
106
- );
104
+ event.preventDefault();
105
+ const result = await validationSchema.safeParseAsync(values);
106
+ if (!result.success) {
107
+ console.error(result.error.issues);
108
+ handleError(result.error);
109
+ return;
110
+ }
107
111
  try {
108
112
  setIsSubmitting(true);
109
- event.preventDefault();
110
- const result = await validationSchema.safeParseAsync(values);
111
- if (result.success) {
112
- reset();
113
- await onSubmit(result.data);
114
- } else {
115
- console.error(result.error.issues);
116
- handleError(result.error);
117
- }
113
+ await Promise.all([
114
+ onSubmit(result.data),
115
+ new Promise<void>((resolve) => {
116
+ return suspendWhileSubmitting ? setTimeout(resolve, 500) : resolve();
117
+ })
118
+ ]);
119
+ reset();
118
120
  } finally {
119
- await minSubmitTime;
120
121
  setIsSubmitting(false);
121
122
  }
122
123
  };
@@ -146,12 +147,13 @@ const Form = <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TS
146
147
  return (
147
148
  <form
148
149
  autoComplete="off"
149
- className={twMerge('w-full', isGrouped ? 'space-y-8 divide-y' : 'space-y-6', className)}
150
+ className={twMerge('relative w-full', isGrouped ? 'space-y-8 divide-y' : 'space-y-6', className)}
150
151
  id={id}
151
152
  onBlur={revalidateOnBlur ? revalidate : undefined}
152
153
  onSubmit={(event) => void handleSubmit(event)}
153
154
  {...props}
154
155
  >
156
+ {isSubmitting && <div className="absolute z-10 h-full w-full cursor-wait" />}
155
157
  {isGrouped ? (
156
158
  content.map((fieldGroup, i) => {
157
159
  return (