@douglasneuroinformatics/libui 4.0.2 → 4.1.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.
- package/dist/components.d.ts +12 -2
- package/dist/components.js +54 -33
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/i18n.d.ts +2 -2
- package/dist/tailwind/globals.css +0 -18
- package/dist/{types-CMuti1SJ.d.ts → types-Dm7os_cB.d.ts} +1 -1
- package/package.json +2 -2
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Dialog/DialogContent.tsx +1 -1
- package/src/components/Dialog/DialogOverlay.tsx +1 -1
- package/src/components/ErrorFallback/ErrorFallback.spec.tsx +14 -0
- package/src/components/ErrorFallback/ErrorFallback.tsx +6 -3
- package/src/components/Form/ErrorMessage.tsx +5 -3
- package/src/components/Form/Form.stories.tsx +24 -0
- package/src/components/Form/Form.test.tsx +65 -0
- package/src/components/Form/Form.tsx +23 -5
- package/src/components/Form/NumberField/NumberFieldInput.tsx +4 -2
- package/src/i18n/types.ts +1 -1
- package/src/tailwind/globals.css +0 -18
package/dist/components.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ import { FormDataType, FormContent, PartialNullableFormDataType } from '@douglas
|
|
|
25
25
|
import { z } from 'zod';
|
|
26
26
|
import * as _radix_ui_react_hover_card from '@radix-ui/react-hover-card';
|
|
27
27
|
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
28
|
-
import { L as Language } from './types-
|
|
28
|
+
import { L as Language } from './types-Dm7os_cB.js';
|
|
29
29
|
import * as _radix_ui_react_menubar from '@radix-ui/react-menubar';
|
|
30
30
|
import { MenubarMenuProps } from '@radix-ui/react-menubar';
|
|
31
31
|
import * as _radix_ui_react_popover from '@radix-ui/react-popover';
|
|
@@ -1283,8 +1283,18 @@ type FormProps<TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<T
|
|
|
1283
1283
|
left?: React.ReactNode;
|
|
1284
1284
|
right?: React.ReactNode;
|
|
1285
1285
|
};
|
|
1286
|
+
beforeSubmit?: (data: NoInfer<TData>) => Promisable<{
|
|
1287
|
+
errorMessage: string;
|
|
1288
|
+
success: false;
|
|
1289
|
+
} | {
|
|
1290
|
+
success: true;
|
|
1291
|
+
}>;
|
|
1286
1292
|
className?: string;
|
|
1287
1293
|
content: FormContent<TData>;
|
|
1294
|
+
customStyles?: {
|
|
1295
|
+
resetBtn?: string;
|
|
1296
|
+
submitBtn?: string;
|
|
1297
|
+
};
|
|
1288
1298
|
fieldsFooter?: React.ReactNode;
|
|
1289
1299
|
id?: string;
|
|
1290
1300
|
initialValues?: PartialNullableFormDataType<NoInfer<TData>>;
|
|
@@ -1298,7 +1308,7 @@ type FormProps<TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<T
|
|
|
1298
1308
|
suspendWhileSubmitting?: boolean;
|
|
1299
1309
|
validationSchema: z.ZodType<TData>;
|
|
1300
1310
|
};
|
|
1301
|
-
declare const Form: <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TSchema> = z.TypeOf<TSchema>>({ additionalButtons, className, content, fieldsFooter, id, initialValues, onError, onSubmit, preventResetValuesOnReset, readOnly, resetBtn, revalidateOnBlur, submitBtnLabel, suspendWhileSubmitting, validationSchema, ...props }: FormProps<TSchema, TData>) => react_jsx_runtime.JSX.Element;
|
|
1311
|
+
declare const Form: <TSchema extends z.ZodType<FormDataType>, TData extends z.TypeOf<TSchema> = z.TypeOf<TSchema>>({ additionalButtons, beforeSubmit, className, content, customStyles, fieldsFooter, id, initialValues, onError, onSubmit, preventResetValuesOnReset, readOnly, resetBtn, revalidateOnBlur, submitBtnLabel, suspendWhileSubmitting, validationSchema, ...props }: FormProps<TSchema, TData>) => react_jsx_runtime.JSX.Element;
|
|
1302
1312
|
|
|
1303
1313
|
type HeadingProps = {
|
|
1304
1314
|
children: string;
|
package/dist/components.js
CHANGED
|
@@ -327,7 +327,7 @@ var BUTTON_ICON_SIZE = {
|
|
|
327
327
|
sm: 14
|
|
328
328
|
};
|
|
329
329
|
var buttonVariants = cva(
|
|
330
|
-
"flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
330
|
+
"flex items-center justify-center whitespace-nowrap cursor-pointer rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
331
331
|
{
|
|
332
332
|
defaultVariants: {
|
|
333
333
|
size: "md",
|
|
@@ -1861,7 +1861,7 @@ var DialogOverlay = forwardRef63(function DialogOverlay2({ className, ...props }
|
|
|
1861
1861
|
Overlay2,
|
|
1862
1862
|
{
|
|
1863
1863
|
className: cn(
|
|
1864
|
-
"
|
|
1864
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80 duration-200",
|
|
1865
1865
|
className
|
|
1866
1866
|
),
|
|
1867
1867
|
ref,
|
|
@@ -1879,7 +1879,7 @@ var DialogContent = forwardRef64(function DialogContent2({ children, className,
|
|
|
1879
1879
|
Content6,
|
|
1880
1880
|
{
|
|
1881
1881
|
className: cn(
|
|
1882
|
-
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95
|
|
1882
|
+
"bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg",
|
|
1883
1883
|
className
|
|
1884
1884
|
),
|
|
1885
1885
|
ref,
|
|
@@ -2018,25 +2018,32 @@ var ErrorFallback = ({ error }) => {
|
|
|
2018
2018
|
useEffect2(() => {
|
|
2019
2019
|
console.error(error);
|
|
2020
2020
|
}, [error]);
|
|
2021
|
-
return /* @__PURE__ */ jsxs24(
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
className: "text-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2021
|
+
return /* @__PURE__ */ jsxs24(
|
|
2022
|
+
"div",
|
|
2023
|
+
{
|
|
2024
|
+
className: "flex min-h-screen flex-col items-center justify-center gap-1 p-3 text-center",
|
|
2025
|
+
"data-testid": "error-fallback",
|
|
2026
|
+
children: [
|
|
2027
|
+
/* @__PURE__ */ jsx90("h1", { className: "text-muted-foreground text-sm font-semibold tracking-wide uppercase", children: "Unexpected Error" }),
|
|
2028
|
+
/* @__PURE__ */ jsx90("h3", { className: "text-3xl font-extrabold tracking-tight sm:text-4xl md:text-5xl", children: "Something Went Wrong" }),
|
|
2029
|
+
/* @__PURE__ */ jsx90("p", { className: "text-muted-foreground mt-2 max-w-prose text-sm sm:text-base", children: "We apologize for the inconvenience. Please contact us for further assistance." }),
|
|
2030
|
+
/* @__PURE__ */ jsx90("div", { className: "mt-6", children: /* @__PURE__ */ jsxs24(
|
|
2031
|
+
"button",
|
|
2032
|
+
{
|
|
2033
|
+
className: "text-sky-800 underline-offset-4 hover:text-sky-700 hover:underline dark:text-sky-200 dark:hover:text-sky-300",
|
|
2034
|
+
type: "button",
|
|
2035
|
+
onClick: () => {
|
|
2036
|
+
window.location.assign(window.location.origin);
|
|
2037
|
+
},
|
|
2038
|
+
children: [
|
|
2039
|
+
"Reload Page",
|
|
2040
|
+
/* @__PURE__ */ jsx90("span", { "aria-hidden": "true", children: " \u2192" })
|
|
2041
|
+
]
|
|
2042
|
+
}
|
|
2043
|
+
) })
|
|
2044
|
+
]
|
|
2045
|
+
}
|
|
2046
|
+
);
|
|
2040
2047
|
};
|
|
2041
2048
|
|
|
2042
2049
|
// src/components/ErrorBoundary/ErrorBoundary.tsx
|
|
@@ -2133,10 +2140,10 @@ var Heading = ({ children, className, variant }) => {
|
|
|
2133
2140
|
import "react";
|
|
2134
2141
|
import { CircleAlertIcon } from "lucide-react";
|
|
2135
2142
|
import { jsx as jsx94, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2136
|
-
var ErrorMessage = ({ error }) => {
|
|
2137
|
-
return error ? /* @__PURE__ */ jsx94("div", { className: "space-y-1.5", children: error.map((message) => /* @__PURE__ */ jsxs26("div", { className: "flex w-full items-center text-sm font-medium
|
|
2143
|
+
var ErrorMessage = ({ className, error }) => {
|
|
2144
|
+
return error ? /* @__PURE__ */ jsx94("div", { className: "space-y-1.5", children: error.map((message) => /* @__PURE__ */ jsxs26("div", { className: cn("text-destructive flex w-full items-center text-sm font-medium", className), children: [
|
|
2138
2145
|
/* @__PURE__ */ jsx94(CircleAlertIcon, { className: "mr-1", style: { strokeWidth: "2px" } }),
|
|
2139
|
-
/* @__PURE__ */ jsx94("span", { children: message })
|
|
2146
|
+
/* @__PURE__ */ jsx94("span", { "data-testid": "error-message-text", children: message })
|
|
2140
2147
|
] }, message)) ?? null }) : null;
|
|
2141
2148
|
};
|
|
2142
2149
|
|
|
@@ -2160,7 +2167,7 @@ import { useEffect as useEffect4, useRef as useRef3 } from "react";
|
|
|
2160
2167
|
import { match as match2 } from "ts-pattern";
|
|
2161
2168
|
|
|
2162
2169
|
// src/components/Form/NumberField/NumberFieldInput.tsx
|
|
2163
|
-
import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
|
|
2170
|
+
import { useEffect as useEffect3, useId as useId2, useRef as useRef2, useState as useState4 } from "react";
|
|
2164
2171
|
import { parseNumber } from "@douglasneuroinformatics/libjs";
|
|
2165
2172
|
|
|
2166
2173
|
// src/components/Input/Input.tsx
|
|
@@ -2271,6 +2278,7 @@ var NumberFieldInput = ({
|
|
|
2271
2278
|
setValue,
|
|
2272
2279
|
value
|
|
2273
2280
|
}) => {
|
|
2281
|
+
const id = useId2();
|
|
2274
2282
|
const [inputValue, setInputValue] = useState4(value?.toString() ?? "");
|
|
2275
2283
|
const valueRef = useRef2(value);
|
|
2276
2284
|
const parseInputValue = (value2) => {
|
|
@@ -2304,13 +2312,14 @@ var NumberFieldInput = ({
|
|
|
2304
2312
|
}, [value]);
|
|
2305
2313
|
return /* @__PURE__ */ jsxs28(FieldGroup, { name, children: [
|
|
2306
2314
|
/* @__PURE__ */ jsxs28(FieldGroup.Row, { children: [
|
|
2307
|
-
/* @__PURE__ */ jsx101(Label3, { children: label }),
|
|
2315
|
+
/* @__PURE__ */ jsx101(Label3, { htmlFor: id, children: label }),
|
|
2308
2316
|
/* @__PURE__ */ jsx101(FieldGroup.Description, { description })
|
|
2309
2317
|
] }),
|
|
2310
2318
|
/* @__PURE__ */ jsx101(
|
|
2311
2319
|
Input,
|
|
2312
2320
|
{
|
|
2313
2321
|
disabled: disabled || readOnly,
|
|
2322
|
+
id,
|
|
2314
2323
|
max,
|
|
2315
2324
|
min,
|
|
2316
2325
|
name,
|
|
@@ -3467,8 +3476,10 @@ function getInitialValues(values) {
|
|
|
3467
3476
|
import { jsx as jsx136, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
3468
3477
|
var Form = ({
|
|
3469
3478
|
additionalButtons,
|
|
3479
|
+
beforeSubmit,
|
|
3470
3480
|
className,
|
|
3471
3481
|
content,
|
|
3482
|
+
customStyles,
|
|
3472
3483
|
fieldsFooter,
|
|
3473
3484
|
id,
|
|
3474
3485
|
initialValues,
|
|
@@ -3492,6 +3503,7 @@ var Form = ({
|
|
|
3492
3503
|
const [isSubmitting, setIsSubmitting] = useState8(false);
|
|
3493
3504
|
const handleError = (error) => {
|
|
3494
3505
|
const fieldErrors = {};
|
|
3506
|
+
const rootErrors2 = [];
|
|
3495
3507
|
for (const issue of error.issues) {
|
|
3496
3508
|
if (issue.path.length > 0) {
|
|
3497
3509
|
const current = get(fieldErrors, issue.path);
|
|
@@ -3501,10 +3513,11 @@ var Form = ({
|
|
|
3501
3513
|
set(fieldErrors, issue.path, [issue.message]);
|
|
3502
3514
|
}
|
|
3503
3515
|
} else {
|
|
3504
|
-
|
|
3516
|
+
rootErrors2.push(issue.message);
|
|
3505
3517
|
}
|
|
3506
3518
|
}
|
|
3507
3519
|
setErrors(fieldErrors);
|
|
3520
|
+
setRootErrors(rootErrors2);
|
|
3508
3521
|
if (onError) {
|
|
3509
3522
|
onError(error);
|
|
3510
3523
|
}
|
|
@@ -3524,6 +3537,14 @@ var Form = ({
|
|
|
3524
3537
|
handleError(result.error);
|
|
3525
3538
|
return;
|
|
3526
3539
|
}
|
|
3540
|
+
if (beforeSubmit) {
|
|
3541
|
+
const beforeSubmitResult = await beforeSubmit(result.data);
|
|
3542
|
+
if (!beforeSubmitResult.success) {
|
|
3543
|
+
setErrors({});
|
|
3544
|
+
setRootErrors([beforeSubmitResult.errorMessage]);
|
|
3545
|
+
return;
|
|
3546
|
+
}
|
|
3547
|
+
}
|
|
3527
3548
|
try {
|
|
3528
3549
|
setIsSubmitting(true);
|
|
3529
3550
|
await Promise.all([
|
|
@@ -3567,7 +3588,7 @@ var Form = ({
|
|
|
3567
3588
|
return /* @__PURE__ */ jsxs47("div", { className: "flex flex-col space-y-6 [&:not(:first-child)]:pt-8", children: [
|
|
3568
3589
|
/* @__PURE__ */ jsxs47("div", { className: "space-y-1", children: [
|
|
3569
3590
|
fieldGroup.title && /* @__PURE__ */ jsx136(Heading, { className: "text-base", variant: "h4", children: fieldGroup.title }),
|
|
3570
|
-
fieldGroup.description && /* @__PURE__ */ jsx136("p", { className: "text-sm
|
|
3591
|
+
fieldGroup.description && /* @__PURE__ */ jsx136("p", { className: "text-muted-foreground text-sm leading-tight italic", children: fieldGroup.description })
|
|
3571
3592
|
] }),
|
|
3572
3593
|
/* @__PURE__ */ jsx136(
|
|
3573
3594
|
FieldsComponent,
|
|
@@ -3592,6 +3613,7 @@ var Form = ({
|
|
|
3592
3613
|
values
|
|
3593
3614
|
}
|
|
3594
3615
|
),
|
|
3616
|
+
Boolean(rootErrors.length) && /* @__PURE__ */ jsx136(ErrorMessage, { className: "-mt-3", error: rootErrors }),
|
|
3595
3617
|
fieldsFooter,
|
|
3596
3618
|
/* @__PURE__ */ jsxs47("div", { className: "flex w-full gap-3", children: [
|
|
3597
3619
|
additionalButtons?.left,
|
|
@@ -3599,7 +3621,7 @@ var Form = ({
|
|
|
3599
3621
|
Button,
|
|
3600
3622
|
{
|
|
3601
3623
|
"aria-label": "Submit",
|
|
3602
|
-
className: "flex w-full items-center justify-center gap-2",
|
|
3624
|
+
className: cn("flex w-full items-center justify-center gap-2", customStyles?.submitBtn),
|
|
3603
3625
|
disabled: readOnly || isSuspended,
|
|
3604
3626
|
type: "submit",
|
|
3605
3627
|
variant: "primary",
|
|
@@ -3628,7 +3650,7 @@ var Form = ({
|
|
|
3628
3650
|
Button,
|
|
3629
3651
|
{
|
|
3630
3652
|
"aria-label": "Reset",
|
|
3631
|
-
className: "block w-full",
|
|
3653
|
+
className: cn("block w-full", customStyles?.resetBtn),
|
|
3632
3654
|
disabled: readOnly,
|
|
3633
3655
|
type: "button",
|
|
3634
3656
|
variant: "secondary",
|
|
@@ -3637,8 +3659,7 @@ var Form = ({
|
|
|
3637
3659
|
}
|
|
3638
3660
|
),
|
|
3639
3661
|
additionalButtons?.right
|
|
3640
|
-
] })
|
|
3641
|
-
Boolean(rootErrors.length) && /* @__PURE__ */ jsx136(ErrorMessage, { error: rootErrors })
|
|
3662
|
+
] })
|
|
3642
3663
|
]
|
|
3643
3664
|
}
|
|
3644
3665
|
);
|