@fuf-stack/uniform 0.0.3 → 0.0.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/dist/Form/index.cjs +5 -143
- package/dist/Form/index.cjs.map +1 -1
- package/dist/Form/index.d.cts +8 -27
- package/dist/Form/index.d.ts +8 -27
- package/dist/Form/index.js +6 -144
- package/dist/Form/index.js.map +1 -1
- package/dist/Form-Bv0R3QNk.d.cts +29 -0
- package/dist/Form-Bv0R3QNk.d.ts +29 -0
- package/dist/Grid/index.cjs +5 -14
- package/dist/Grid/index.cjs.map +1 -1
- package/dist/Grid/index.d.cts +6 -15
- package/dist/Grid/index.d.ts +6 -15
- package/dist/Grid/index.js +5 -14
- package/dist/Grid/index.js.map +1 -1
- package/dist/Grid-DF3L9NF3.d.cts +17 -0
- package/dist/Grid-DF3L9NF3.d.ts +17 -0
- package/dist/SubmitButton/index.cjs +2 -1
- package/dist/SubmitButton/index.cjs.map +1 -1
- package/dist/SubmitButton/index.d.cts +1 -1
- package/dist/SubmitButton/index.d.ts +1 -1
- package/dist/SubmitButton/index.js +1 -0
- package/dist/SubmitButton/index.js.map +1 -1
- package/dist/chunk-4MEKDDB2.js +20 -0
- package/dist/chunk-4MEKDDB2.js.map +1 -0
- package/dist/chunk-BQUVQMFA.js +158 -0
- package/dist/chunk-BQUVQMFA.js.map +1 -0
- package/dist/chunk-II57W3V2.cjs +158 -0
- package/dist/chunk-II57W3V2.cjs.map +1 -0
- package/dist/chunk-ZPFKVKGV.cjs +20 -0
- package/dist/chunk-ZPFKVKGV.cjs.map +1 -0
- package/dist/index.cjs +13 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/package.json +16 -8
package/dist/Form/index.cjs
CHANGED
|
@@ -1,149 +1,11 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunkII57W3V2cjs = require('../chunk-II57W3V2.cjs');
|
|
5
|
+
require('../chunk-WQRM7G4C.cjs');
|
|
6
|
+
require('../chunk-BBB4FEY6.cjs');
|
|
5
7
|
|
|
6
8
|
|
|
7
|
-
var _chunkBBB4FEY6cjs = require('../chunk-BBB4FEY6.cjs');
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
var _react = require('react');
|
|
11
|
-
var _reacthookform = require('react-hook-form');
|
|
12
|
-
var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames);
|
|
13
|
-
|
|
14
|
-
// src/Form/subcomponents/FormDebugViewer.tsx
|
|
15
|
-
|
|
16
|
-
var _fa = require('react-icons/fa');
|
|
17
|
-
var _fa6 = require('react-icons/fa6');
|
|
18
|
-
|
|
19
|
-
var _Button = require('@fuf-stack/pixels/Button'); var _Button2 = _interopRequireDefault(_Button);
|
|
20
|
-
var _Card = require('@fuf-stack/pixels/Card'); var _Card2 = _interopRequireDefault(_Card);
|
|
21
|
-
var _useLocalStorage = require('@fuf-stack/pixels/hooks/useLocalStorage'); var _useLocalStorage2 = _interopRequireDefault(_useLocalStorage);
|
|
22
|
-
var _Json = require('@fuf-stack/pixels/Json'); var _Json2 = _interopRequireDefault(_Json);
|
|
23
|
-
var _jsxruntime = require('react/jsx-runtime');
|
|
24
|
-
var LOCALSTORAGE_DEBUG_KEY = "uniform:form-debug-enabled";
|
|
25
|
-
var FormDebugViewer = ({ className = void 0 }) => {
|
|
26
|
-
const {
|
|
27
|
-
watch,
|
|
28
|
-
formState: { dirtyFields, isValid, isSubmitting },
|
|
29
|
-
validation
|
|
30
|
-
} = _chunkWQRM7G4Ccjs.useFormContext.call(void 0, );
|
|
31
|
-
const [debug, setDebug] = _useLocalStorage2.default.call(void 0, LOCALSTORAGE_DEBUG_KEY, false);
|
|
32
|
-
const [validationErrors, setValidationErrors] = _react.useState.call(void 0, null);
|
|
33
|
-
const formValues = watch();
|
|
34
|
-
_react.useEffect.call(void 0, () => {
|
|
35
|
-
const updateValidationErrors = async () => {
|
|
36
|
-
if (validation) {
|
|
37
|
-
const validateResult = await _optionalChain([validation, 'optionalAccess', _ => _.validateAsync, 'call', _2 => _2(formValues)]);
|
|
38
|
-
setValidationErrors(_optionalChain([validateResult, 'optionalAccess', _3 => _3.errors]));
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
updateValidationErrors();
|
|
42
|
-
}, [JSON.stringify(formValues)]);
|
|
43
|
-
if (!debug) {
|
|
44
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
45
|
-
_Button2.default,
|
|
46
|
-
{
|
|
47
|
-
ariaLabel: "Enable form debug mode",
|
|
48
|
-
onClick: () => setDebug(!debug),
|
|
49
|
-
className: "absolute bottom-2.5 right-2.5 w-5 text-default-400",
|
|
50
|
-
variant: "light",
|
|
51
|
-
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _fa6.FaBug, {})
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
56
|
-
_Card2.default,
|
|
57
|
-
{
|
|
58
|
-
className: _classnames2.default.call(void 0, className),
|
|
59
|
-
header: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between", children: [
|
|
60
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-lg", children: "Debug Mode" }),
|
|
61
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
62
|
-
_Button2.default,
|
|
63
|
-
{
|
|
64
|
-
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _fa.FaTimes, { className: "text-danger" }),
|
|
65
|
-
onClick: () => setDebug(false),
|
|
66
|
-
size: "sm",
|
|
67
|
-
variant: "flat"
|
|
68
|
-
}
|
|
69
|
-
)
|
|
70
|
-
] }),
|
|
71
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
72
|
-
_Json2.default,
|
|
73
|
-
{
|
|
74
|
-
value: {
|
|
75
|
-
values: formValues,
|
|
76
|
-
errors: validationErrors,
|
|
77
|
-
dirtyFields,
|
|
78
|
-
isValid,
|
|
79
|
-
isSubmitting
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
);
|
|
85
|
-
};
|
|
86
|
-
var FormDebugViewer_default = FormDebugViewer;
|
|
87
|
-
|
|
88
|
-
// src/Form/Form.tsx
|
|
89
|
-
|
|
90
|
-
var removeNullishFields = (obj) => {
|
|
91
|
-
return JSON.parse(
|
|
92
|
-
JSON.stringify(obj, (_key, value) => {
|
|
93
|
-
return value === null ? void 0 : value;
|
|
94
|
-
})
|
|
95
|
-
);
|
|
96
|
-
};
|
|
97
|
-
var Form = ({
|
|
98
|
-
children,
|
|
99
|
-
className = void 0,
|
|
100
|
-
initialValues = void 0,
|
|
101
|
-
name = void 0,
|
|
102
|
-
onSubmit,
|
|
103
|
-
testId = void 0,
|
|
104
|
-
validation = void 0,
|
|
105
|
-
validationTrigger = "all"
|
|
106
|
-
}) => {
|
|
107
|
-
const methods = _reacthookform.useForm.call(void 0,
|
|
108
|
-
validation ? {
|
|
109
|
-
defaultValues: initialValues,
|
|
110
|
-
resolver: async (values) => {
|
|
111
|
-
const { data, errors, ...rest } = await validation.validateAsync(
|
|
112
|
-
removeNullishFields(values)
|
|
113
|
-
);
|
|
114
|
-
return { values: data || {}, errors: errors || {}, ...rest };
|
|
115
|
-
},
|
|
116
|
-
// set rhf mode
|
|
117
|
-
// see: https://react-hook-form.com/docs/useform#mode
|
|
118
|
-
mode: validationTrigger === "all-instant" ? "all" : validationTrigger
|
|
119
|
-
} : {
|
|
120
|
-
defaultValues: initialValues
|
|
121
|
-
}
|
|
122
|
-
);
|
|
123
|
-
_react.useEffect.call(void 0, () => {
|
|
124
|
-
if (validationTrigger === "all-instant") {
|
|
125
|
-
methods.trigger();
|
|
126
|
-
}
|
|
127
|
-
}, []);
|
|
128
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWQRM7G4Ccjs.FormContext_default, { ...methods, validation, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between gap-6", children: [
|
|
129
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
130
|
-
"form",
|
|
131
|
-
{
|
|
132
|
-
className: _classnames2.default.call(void 0, "flex-grow", className),
|
|
133
|
-
"data-testid": _chunkBBB4FEY6cjs.slugify.call(void 0, testId || name || ""),
|
|
134
|
-
name,
|
|
135
|
-
onSubmit: methods.handleSubmit(onSubmit),
|
|
136
|
-
children
|
|
137
|
-
}
|
|
138
|
-
),
|
|
139
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormDebugViewer_default, { className: "w-96 flex-shrink" })
|
|
140
|
-
] }) });
|
|
141
|
-
};
|
|
142
|
-
var Form_default = Form;
|
|
143
|
-
|
|
144
|
-
// src/Form/index.ts
|
|
145
|
-
var Form_default2 = Form_default;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
exports.default = Form_default2;
|
|
10
|
+
exports.Form = _chunkII57W3V2cjs.Form_default; exports.default = _chunkII57W3V2cjs.Form_default2;
|
|
149
11
|
//# sourceMappingURL=index.cjs.map
|
package/dist/Form/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|
package/dist/Form/index.d.cts
CHANGED
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import { F as Form } from '../Form-Bv0R3QNk.cjs';
|
|
2
|
+
export { a as FormProps } from '../Form-Bv0R3QNk.cjs';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import '@fuf-stack/veto';
|
|
5
|
+
import 'react';
|
|
6
|
+
import 'react-hook-form';
|
|
5
7
|
|
|
6
|
-
interface FormProps {
|
|
7
|
-
/** form children */
|
|
8
|
-
children: ReactNode | ReactNode[];
|
|
9
|
-
/** CSS class name */
|
|
10
|
-
className?: string | string[];
|
|
11
|
-
/** initial form values */
|
|
12
|
-
initialValues?: FieldValues;
|
|
13
|
-
/** name of the form */
|
|
14
|
-
name?: string;
|
|
15
|
-
/** form submit handler */
|
|
16
|
-
onSubmit: SubmitHandler<FieldValues>;
|
|
17
|
-
/** HTML data-testid attribute used in e2e tests */
|
|
18
|
-
testId?: string;
|
|
19
|
-
/** veto validation schema */
|
|
20
|
-
validation?: VetoInstance;
|
|
21
|
-
/** when the validation should be triggered */
|
|
22
|
-
validationTrigger?: 'onChange' | 'onBlur' | 'onSubmit' | 'onTouched' | 'all' | 'all-instant';
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Form component that has to wrap every uniform
|
|
26
|
-
*/
|
|
27
|
-
declare const Form: ({ children, className, initialValues, name, onSubmit, testId, validation, validationTrigger, }: FormProps) => react_jsx_runtime.JSX.Element;
|
|
28
8
|
|
|
29
|
-
|
|
9
|
+
|
|
10
|
+
export { Form, Form as default };
|
package/dist/Form/index.d.ts
CHANGED
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import { F as Form } from '../Form-Bv0R3QNk.js';
|
|
2
|
+
export { a as FormProps } from '../Form-Bv0R3QNk.js';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import '@fuf-stack/veto';
|
|
5
|
+
import 'react';
|
|
6
|
+
import 'react-hook-form';
|
|
5
7
|
|
|
6
|
-
interface FormProps {
|
|
7
|
-
/** form children */
|
|
8
|
-
children: ReactNode | ReactNode[];
|
|
9
|
-
/** CSS class name */
|
|
10
|
-
className?: string | string[];
|
|
11
|
-
/** initial form values */
|
|
12
|
-
initialValues?: FieldValues;
|
|
13
|
-
/** name of the form */
|
|
14
|
-
name?: string;
|
|
15
|
-
/** form submit handler */
|
|
16
|
-
onSubmit: SubmitHandler<FieldValues>;
|
|
17
|
-
/** HTML data-testid attribute used in e2e tests */
|
|
18
|
-
testId?: string;
|
|
19
|
-
/** veto validation schema */
|
|
20
|
-
validation?: VetoInstance;
|
|
21
|
-
/** when the validation should be triggered */
|
|
22
|
-
validationTrigger?: 'onChange' | 'onBlur' | 'onSubmit' | 'onTouched' | 'all' | 'all-instant';
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Form component that has to wrap every uniform
|
|
26
|
-
*/
|
|
27
|
-
declare const Form: ({ children, className, initialValues, name, onSubmit, testId, validation, validationTrigger, }: FormProps) => react_jsx_runtime.JSX.Element;
|
|
28
8
|
|
|
29
|
-
|
|
9
|
+
|
|
10
|
+
export { Form, Form as default };
|
package/dist/Form/index.js
CHANGED
|
@@ -1,149 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
} from "../chunk-V46BHM2U.js";
|
|
8
|
-
|
|
9
|
-
// src/Form/Form.tsx
|
|
10
|
-
import { useEffect as useEffect2 } from "react";
|
|
11
|
-
import { useForm } from "react-hook-form";
|
|
12
|
-
import cn2 from "classnames";
|
|
13
|
-
|
|
14
|
-
// src/Form/subcomponents/FormDebugViewer.tsx
|
|
15
|
-
import { useEffect, useState } from "react";
|
|
16
|
-
import { FaTimes } from "react-icons/fa";
|
|
17
|
-
import { FaBug } from "react-icons/fa6";
|
|
18
|
-
import cn from "classnames";
|
|
19
|
-
import Button from "@fuf-stack/pixels/Button";
|
|
20
|
-
import Card from "@fuf-stack/pixels/Card";
|
|
21
|
-
import useLocalStorage from "@fuf-stack/pixels/hooks/useLocalStorage";
|
|
22
|
-
import Json from "@fuf-stack/pixels/Json";
|
|
23
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24
|
-
var LOCALSTORAGE_DEBUG_KEY = "uniform:form-debug-enabled";
|
|
25
|
-
var FormDebugViewer = ({ className = void 0 }) => {
|
|
26
|
-
const {
|
|
27
|
-
watch,
|
|
28
|
-
formState: { dirtyFields, isValid, isSubmitting },
|
|
29
|
-
validation
|
|
30
|
-
} = useFormContext();
|
|
31
|
-
const [debug, setDebug] = useLocalStorage(LOCALSTORAGE_DEBUG_KEY, false);
|
|
32
|
-
const [validationErrors, setValidationErrors] = useState(null);
|
|
33
|
-
const formValues = watch();
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
const updateValidationErrors = async () => {
|
|
36
|
-
if (validation) {
|
|
37
|
-
const validateResult = await validation?.validateAsync(formValues);
|
|
38
|
-
setValidationErrors(validateResult?.errors);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
updateValidationErrors();
|
|
42
|
-
}, [JSON.stringify(formValues)]);
|
|
43
|
-
if (!debug) {
|
|
44
|
-
return /* @__PURE__ */ jsx(
|
|
45
|
-
Button,
|
|
46
|
-
{
|
|
47
|
-
ariaLabel: "Enable form debug mode",
|
|
48
|
-
onClick: () => setDebug(!debug),
|
|
49
|
-
className: "absolute bottom-2.5 right-2.5 w-5 text-default-400",
|
|
50
|
-
variant: "light",
|
|
51
|
-
icon: /* @__PURE__ */ jsx(FaBug, {})
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
return /* @__PURE__ */ jsx(
|
|
56
|
-
Card,
|
|
57
|
-
{
|
|
58
|
-
className: cn(className),
|
|
59
|
-
header: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-row justify-between", children: [
|
|
60
|
-
/* @__PURE__ */ jsx("span", { className: "text-lg", children: "Debug Mode" }),
|
|
61
|
-
/* @__PURE__ */ jsx(
|
|
62
|
-
Button,
|
|
63
|
-
{
|
|
64
|
-
icon: /* @__PURE__ */ jsx(FaTimes, { className: "text-danger" }),
|
|
65
|
-
onClick: () => setDebug(false),
|
|
66
|
-
size: "sm",
|
|
67
|
-
variant: "flat"
|
|
68
|
-
}
|
|
69
|
-
)
|
|
70
|
-
] }),
|
|
71
|
-
children: /* @__PURE__ */ jsx(
|
|
72
|
-
Json,
|
|
73
|
-
{
|
|
74
|
-
value: {
|
|
75
|
-
values: formValues,
|
|
76
|
-
errors: validationErrors,
|
|
77
|
-
dirtyFields,
|
|
78
|
-
isValid,
|
|
79
|
-
isSubmitting
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
);
|
|
85
|
-
};
|
|
86
|
-
var FormDebugViewer_default = FormDebugViewer;
|
|
87
|
-
|
|
88
|
-
// src/Form/Form.tsx
|
|
89
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
90
|
-
var removeNullishFields = (obj) => {
|
|
91
|
-
return JSON.parse(
|
|
92
|
-
JSON.stringify(obj, (_key, value) => {
|
|
93
|
-
return value === null ? void 0 : value;
|
|
94
|
-
})
|
|
95
|
-
);
|
|
96
|
-
};
|
|
97
|
-
var Form = ({
|
|
98
|
-
children,
|
|
99
|
-
className = void 0,
|
|
100
|
-
initialValues = void 0,
|
|
101
|
-
name = void 0,
|
|
102
|
-
onSubmit,
|
|
103
|
-
testId = void 0,
|
|
104
|
-
validation = void 0,
|
|
105
|
-
validationTrigger = "all"
|
|
106
|
-
}) => {
|
|
107
|
-
const methods = useForm(
|
|
108
|
-
validation ? {
|
|
109
|
-
defaultValues: initialValues,
|
|
110
|
-
resolver: async (values) => {
|
|
111
|
-
const { data, errors, ...rest } = await validation.validateAsync(
|
|
112
|
-
removeNullishFields(values)
|
|
113
|
-
);
|
|
114
|
-
return { values: data || {}, errors: errors || {}, ...rest };
|
|
115
|
-
},
|
|
116
|
-
// set rhf mode
|
|
117
|
-
// see: https://react-hook-form.com/docs/useform#mode
|
|
118
|
-
mode: validationTrigger === "all-instant" ? "all" : validationTrigger
|
|
119
|
-
} : {
|
|
120
|
-
defaultValues: initialValues
|
|
121
|
-
}
|
|
122
|
-
);
|
|
123
|
-
useEffect2(() => {
|
|
124
|
-
if (validationTrigger === "all-instant") {
|
|
125
|
-
methods.trigger();
|
|
126
|
-
}
|
|
127
|
-
}, []);
|
|
128
|
-
return /* @__PURE__ */ jsx2(FormContext_default, { ...methods, validation, children: /* @__PURE__ */ jsxs2("div", { className: "flex w-full flex-row justify-between gap-6", children: [
|
|
129
|
-
/* @__PURE__ */ jsx2(
|
|
130
|
-
"form",
|
|
131
|
-
{
|
|
132
|
-
className: cn2("flex-grow", className),
|
|
133
|
-
"data-testid": slugify(testId || name || ""),
|
|
134
|
-
name,
|
|
135
|
-
onSubmit: methods.handleSubmit(onSubmit),
|
|
136
|
-
children
|
|
137
|
-
}
|
|
138
|
-
),
|
|
139
|
-
/* @__PURE__ */ jsx2(FormDebugViewer_default, { className: "w-96 flex-shrink" })
|
|
140
|
-
] }) });
|
|
141
|
-
};
|
|
142
|
-
var Form_default = Form;
|
|
143
|
-
|
|
144
|
-
// src/Form/index.ts
|
|
145
|
-
var Form_default2 = Form_default;
|
|
2
|
+
Form_default,
|
|
3
|
+
Form_default2
|
|
4
|
+
} from "../chunk-BQUVQMFA.js";
|
|
5
|
+
import "../chunk-BCMPSLSG.js";
|
|
6
|
+
import "../chunk-V46BHM2U.js";
|
|
146
7
|
export {
|
|
8
|
+
Form_default as Form,
|
|
147
9
|
Form_default2 as default
|
|
148
10
|
};
|
|
149
11
|
//# sourceMappingURL=index.js.map
|
package/dist/Form/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { VetoInstance } from '@fuf-stack/veto';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
import { FieldValues, SubmitHandler } from 'react-hook-form';
|
|
5
|
+
|
|
6
|
+
interface FormProps {
|
|
7
|
+
/** form children */
|
|
8
|
+
children: ReactNode | ReactNode[];
|
|
9
|
+
/** CSS class name */
|
|
10
|
+
className?: string | string[];
|
|
11
|
+
/** initial form values */
|
|
12
|
+
initialValues?: FieldValues;
|
|
13
|
+
/** name of the form */
|
|
14
|
+
name?: string;
|
|
15
|
+
/** form submit handler */
|
|
16
|
+
onSubmit: SubmitHandler<FieldValues>;
|
|
17
|
+
/** HTML data-testid attribute used in e2e tests */
|
|
18
|
+
testId?: string;
|
|
19
|
+
/** veto validation schema */
|
|
20
|
+
validation?: VetoInstance;
|
|
21
|
+
/** when the validation should be triggered */
|
|
22
|
+
validationTrigger?: 'onChange' | 'onBlur' | 'onSubmit' | 'onTouched' | 'all' | 'all-instant';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Form component that has to wrap every uniform
|
|
26
|
+
*/
|
|
27
|
+
declare const Form: ({ children, className, initialValues, name, onSubmit, testId, validation, validationTrigger, }: FormProps) => react_jsx_runtime.JSX.Element;
|
|
28
|
+
|
|
29
|
+
export { Form as F, type FormProps as a };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { VetoInstance } from '@fuf-stack/veto';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
import { FieldValues, SubmitHandler } from 'react-hook-form';
|
|
5
|
+
|
|
6
|
+
interface FormProps {
|
|
7
|
+
/** form children */
|
|
8
|
+
children: ReactNode | ReactNode[];
|
|
9
|
+
/** CSS class name */
|
|
10
|
+
className?: string | string[];
|
|
11
|
+
/** initial form values */
|
|
12
|
+
initialValues?: FieldValues;
|
|
13
|
+
/** name of the form */
|
|
14
|
+
name?: string;
|
|
15
|
+
/** form submit handler */
|
|
16
|
+
onSubmit: SubmitHandler<FieldValues>;
|
|
17
|
+
/** HTML data-testid attribute used in e2e tests */
|
|
18
|
+
testId?: string;
|
|
19
|
+
/** veto validation schema */
|
|
20
|
+
validation?: VetoInstance;
|
|
21
|
+
/** when the validation should be triggered */
|
|
22
|
+
validationTrigger?: 'onChange' | 'onBlur' | 'onSubmit' | 'onTouched' | 'all' | 'all-instant';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Form component that has to wrap every uniform
|
|
26
|
+
*/
|
|
27
|
+
declare const Form: ({ children, className, initialValues, name, onSubmit, testId, validation, validationTrigger, }: FormProps) => react_jsx_runtime.JSX.Element;
|
|
28
|
+
|
|
29
|
+
export { Form as F, type FormProps as a };
|
package/dist/Grid/index.cjs
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
-
var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames);
|
|
3
|
-
var _jsxruntime = require('react/jsx-runtime');
|
|
4
|
-
var Grid = ({
|
|
5
|
-
children = null,
|
|
6
|
-
className = void 0,
|
|
7
|
-
testId = void 0
|
|
8
|
-
}) => {
|
|
9
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _classnames2.default.call(void 0, "grid gap-6", className), "data-testid": testId, children });
|
|
10
|
-
};
|
|
11
|
-
var Grid_default = Grid;
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
12
2
|
|
|
13
|
-
// src/Grid/index.ts
|
|
14
|
-
var Grid_default2 = Grid_default;
|
|
15
3
|
|
|
4
|
+
var _chunkZPFKVKGVcjs = require('../chunk-ZPFKVKGV.cjs');
|
|
16
5
|
|
|
17
|
-
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
exports.Grid = _chunkZPFKVKGVcjs.Grid_default; exports.default = _chunkZPFKVKGVcjs.Grid_default2;
|
|
18
9
|
//# sourceMappingURL=index.cjs.map
|
package/dist/Grid/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|
package/dist/Grid/index.d.cts
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { G as Grid } from '../Grid-DF3L9NF3.cjs';
|
|
2
|
+
export { a as GridProps } from '../Grid-DF3L9NF3.cjs';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
3
5
|
|
|
4
|
-
interface GridProps {
|
|
5
|
-
/** child components */
|
|
6
|
-
children?: ReactNode;
|
|
7
|
-
/** CSS class name */
|
|
8
|
-
className?: string;
|
|
9
|
-
/** HTML data-testid attribute used in e2e tests */
|
|
10
|
-
testId?: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Defines the default grid for form components
|
|
14
|
-
*/
|
|
15
|
-
declare const Grid: ({ children, className, testId, }: GridProps) => react_jsx_runtime.JSX.Element;
|
|
16
6
|
|
|
17
|
-
|
|
7
|
+
|
|
8
|
+
export { Grid, Grid as default };
|
package/dist/Grid/index.d.ts
CHANGED
|
@@ -1,17 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { G as Grid } from '../Grid-DF3L9NF3.js';
|
|
2
|
+
export { a as GridProps } from '../Grid-DF3L9NF3.js';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
3
5
|
|
|
4
|
-
interface GridProps {
|
|
5
|
-
/** child components */
|
|
6
|
-
children?: ReactNode;
|
|
7
|
-
/** CSS class name */
|
|
8
|
-
className?: string;
|
|
9
|
-
/** HTML data-testid attribute used in e2e tests */
|
|
10
|
-
testId?: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Defines the default grid for form components
|
|
14
|
-
*/
|
|
15
|
-
declare const Grid: ({ children, className, testId, }: GridProps) => react_jsx_runtime.JSX.Element;
|
|
16
6
|
|
|
17
|
-
|
|
7
|
+
|
|
8
|
+
export { Grid, Grid as default };
|
package/dist/Grid/index.js
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
children = null,
|
|
6
|
-
className = void 0,
|
|
7
|
-
testId = void 0
|
|
8
|
-
}) => {
|
|
9
|
-
return /* @__PURE__ */ jsx("div", { className: cn("grid gap-6", className), "data-testid": testId, children });
|
|
10
|
-
};
|
|
11
|
-
var Grid_default = Grid;
|
|
12
|
-
|
|
13
|
-
// src/Grid/index.ts
|
|
14
|
-
var Grid_default2 = Grid_default;
|
|
1
|
+
import {
|
|
2
|
+
Grid_default,
|
|
3
|
+
Grid_default2
|
|
4
|
+
} from "../chunk-4MEKDDB2.js";
|
|
15
5
|
export {
|
|
6
|
+
Grid_default as Grid,
|
|
16
7
|
Grid_default2 as default
|
|
17
8
|
};
|
|
18
9
|
//# sourceMappingURL=index.js.map
|
package/dist/Grid/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface GridProps {
|
|
5
|
+
/** child components */
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
/** CSS class name */
|
|
8
|
+
className?: string;
|
|
9
|
+
/** HTML data-testid attribute used in e2e tests */
|
|
10
|
+
testId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Defines the default grid for form components
|
|
14
|
+
*/
|
|
15
|
+
declare const Grid: ({ children, className, testId, }: GridProps) => react_jsx_runtime.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { Grid as G, type GridProps as a };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
interface GridProps {
|
|
5
|
+
/** child components */
|
|
6
|
+
children?: ReactNode;
|
|
7
|
+
/** CSS class name */
|
|
8
|
+
className?: string;
|
|
9
|
+
/** HTML data-testid attribute used in e2e tests */
|
|
10
|
+
testId?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Defines the default grid for form components
|
|
14
|
+
*/
|
|
15
|
+
declare const Grid: ({ children, className, testId, }: GridProps) => react_jsx_runtime.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { Grid as G, type GridProps as a };
|
|
@@ -40,5 +40,6 @@ var SubmitButton_default = SubmitButton;
|
|
|
40
40
|
var SubmitButton_default2 = SubmitButton_default;
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
|
|
44
|
+
exports.SubmitButton = SubmitButton_default; exports.default = SubmitButton_default2;
|
|
44
45
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/SubmitButton/SubmitButton.tsx","../../src/SubmitButton/index.ts"],"names":["SubmitButton_default"],"mappings":";;;;;;;;AAGA,OAAO,QAAQ;AAEf,OAAO,YAAY;AAoCf;AAbJ,IAAM,eAAe,CAAC;AAAA,EACpB,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AACX,MAAyB;AACvB,QAAM;AAAA,IACJ,WAAW,EAAE,SAAS,cAAc,aAAa;AAAA,EACnD,IAAI,eAAe;AAEnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,SAAS;AAAA,MACvB;AAAA,MACA,QAAQ,QAAQ,MAAM;AAAA,MACtB,UAAU,CAAC,WAAW,gBAAgB;AAAA,MACtC;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MAEJ;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,uBAAQ;;;
|
|
1
|
+
{"version":3,"sources":["../../src/SubmitButton/SubmitButton.tsx","../../src/SubmitButton/index.ts"],"names":["SubmitButton_default"],"mappings":";;;;;;;;AAGA,OAAO,QAAQ;AAEf,OAAO,YAAY;AAoCf;AAbJ,IAAM,eAAe,CAAC;AAAA,EACpB,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AACX,MAAyB;AACvB,QAAM;AAAA,IACJ,WAAW,EAAE,SAAS,cAAc,aAAa;AAAA,EACnD,IAAI,eAAe;AAEnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,SAAS;AAAA,MACvB;AAAA,MACA,QAAQ,QAAQ,MAAM;AAAA,MACtB,UAAU,CAAC,WAAW,gBAAgB;AAAA,MACtC;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MAEJ;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,uBAAQ;;;ACjDf,IAAOA,wBAAQ","sourcesContent":["import type { ButtonProps } from '@fuf-stack/pixels/Button';\nimport type { ReactNode } from 'react';\n\nimport cn from 'classnames';\n\nimport Button from '@fuf-stack/pixels/Button';\n\nimport { slugify } from '../helpers';\nimport { useFormContext } from '../hooks';\n\nexport interface SubmitButtonProps {\n /** child components */\n children?: ReactNode;\n /** CSS class name */\n className?: string | string[];\n /** color of the button */\n color?: ButtonProps['color'];\n /** If set loading animation is shown */\n loading?: boolean;\n /** function called when the button is pressed. */\n onClick?: ButtonProps['onClick'];\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * From SubmitButton\n */\nconst SubmitButton = ({\n children = 'Submit',\n className = undefined,\n color = 'success',\n loading = false,\n onClick = undefined,\n testId = 'form_submit_button',\n}: SubmitButtonProps) => {\n const {\n formState: { isValid, isSubmitting, isValidating },\n } = useFormContext();\n\n return (\n <Button\n className={cn(className)}\n color={color}\n testId={slugify(testId)}\n disabled={!isValid || isSubmitting || isValidating}\n loading={loading}\n onClick={onClick}\n type=\"submit\"\n >\n {children}\n </Button>\n );\n};\n\nexport default SubmitButton;\n","import SubmitButton from './SubmitButton';\n\nexport type { SubmitButtonProps } from './SubmitButton';\n\nexport { SubmitButton };\n\nexport default SubmitButton;\n"]}
|
|
@@ -21,4 +21,4 @@ interface SubmitButtonProps {
|
|
|
21
21
|
*/
|
|
22
22
|
declare const SubmitButton: ({ children, className, color, loading, onClick, testId, }: SubmitButtonProps) => react_jsx_runtime.JSX.Element;
|
|
23
23
|
|
|
24
|
-
export { SubmitButton as default };
|
|
24
|
+
export { SubmitButton, type SubmitButtonProps, SubmitButton as default };
|
|
@@ -21,4 +21,4 @@ interface SubmitButtonProps {
|
|
|
21
21
|
*/
|
|
22
22
|
declare const SubmitButton: ({ children, className, color, loading, onClick, testId, }: SubmitButtonProps) => react_jsx_runtime.JSX.Element;
|
|
23
23
|
|
|
24
|
-
export { SubmitButton as default };
|
|
24
|
+
export { SubmitButton, type SubmitButtonProps, SubmitButton as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/SubmitButton/SubmitButton.tsx","../../src/SubmitButton/index.ts"],"sourcesContent":["import type { ButtonProps } from '@fuf-stack/pixels/Button';\nimport type { ReactNode } from 'react';\n\nimport cn from 'classnames';\n\nimport Button from '@fuf-stack/pixels/Button';\n\nimport { slugify } from '../helpers';\nimport { useFormContext } from '../hooks';\n\
|
|
1
|
+
{"version":3,"sources":["../../src/SubmitButton/SubmitButton.tsx","../../src/SubmitButton/index.ts"],"sourcesContent":["import type { ButtonProps } from '@fuf-stack/pixels/Button';\nimport type { ReactNode } from 'react';\n\nimport cn from 'classnames';\n\nimport Button from '@fuf-stack/pixels/Button';\n\nimport { slugify } from '../helpers';\nimport { useFormContext } from '../hooks';\n\nexport interface SubmitButtonProps {\n /** child components */\n children?: ReactNode;\n /** CSS class name */\n className?: string | string[];\n /** color of the button */\n color?: ButtonProps['color'];\n /** If set loading animation is shown */\n loading?: boolean;\n /** function called when the button is pressed. */\n onClick?: ButtonProps['onClick'];\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * From SubmitButton\n */\nconst SubmitButton = ({\n children = 'Submit',\n className = undefined,\n color = 'success',\n loading = false,\n onClick = undefined,\n testId = 'form_submit_button',\n}: SubmitButtonProps) => {\n const {\n formState: { isValid, isSubmitting, isValidating },\n } = useFormContext();\n\n return (\n <Button\n className={cn(className)}\n color={color}\n testId={slugify(testId)}\n disabled={!isValid || isSubmitting || isValidating}\n loading={loading}\n onClick={onClick}\n type=\"submit\"\n >\n {children}\n </Button>\n );\n};\n\nexport default SubmitButton;\n","import SubmitButton from './SubmitButton';\n\nexport type { SubmitButtonProps } from './SubmitButton';\n\nexport { SubmitButton };\n\nexport default SubmitButton;\n"],"mappings":";;;;;;;;AAGA,OAAO,QAAQ;AAEf,OAAO,YAAY;AAoCf;AAbJ,IAAM,eAAe,CAAC;AAAA,EACpB,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,SAAS;AACX,MAAyB;AACvB,QAAM;AAAA,IACJ,WAAW,EAAE,SAAS,cAAc,aAAa;AAAA,EACnD,IAAI,eAAe;AAEnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,SAAS;AAAA,MACvB;AAAA,MACA,QAAQ,QAAQ,MAAM;AAAA,MACtB,UAAU,CAAC,WAAW,gBAAgB;AAAA,MACtC;AAAA,MACA;AAAA,MACA,MAAK;AAAA,MAEJ;AAAA;AAAA,EACH;AAEJ;AAEA,IAAO,uBAAQ;;;ACjDf,IAAOA,wBAAQ;","names":["SubmitButton_default"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/Grid/Grid.tsx
|
|
2
|
+
import cn from "classnames";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
var Grid = ({
|
|
5
|
+
children = null,
|
|
6
|
+
className = void 0,
|
|
7
|
+
testId = void 0
|
|
8
|
+
}) => {
|
|
9
|
+
return /* @__PURE__ */ jsx("div", { className: cn("grid gap-6", className), "data-testid": testId, children });
|
|
10
|
+
};
|
|
11
|
+
var Grid_default = Grid;
|
|
12
|
+
|
|
13
|
+
// src/Grid/index.ts
|
|
14
|
+
var Grid_default2 = Grid_default;
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
Grid_default,
|
|
18
|
+
Grid_default2
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=chunk-4MEKDDB2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Grid/Grid.tsx","../src/Grid/index.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport cn from 'classnames';\n\nexport interface GridProps {\n /** child components */\n children?: ReactNode;\n /** CSS class name */\n className?: string;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * Defines the default grid for form components\n */\nconst Grid = ({\n children = null,\n className = undefined,\n testId = undefined,\n}: GridProps) => {\n return (\n <div className={cn('grid gap-6', className)} data-testid={testId}>\n {children}\n </div>\n );\n};\n\nexport default Grid;\n","import Grid from './Grid';\n\nexport type { GridProps } from './Grid';\n\nexport { Grid };\n\nexport default Grid;\n"],"mappings":";AAEA,OAAO,QAAQ;AAoBX;AANJ,IAAM,OAAO,CAAC;AAAA,EACZ,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,SAAS;AACX,MAAiB;AACf,SACE,oBAAC,SAAI,WAAW,GAAG,cAAc,SAAS,GAAG,eAAa,QACvD,UACH;AAEJ;AAEA,IAAO,eAAQ;;;ACtBf,IAAOA,gBAAQ;","names":["Grid_default"]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FormContext_default,
|
|
3
|
+
useFormContext
|
|
4
|
+
} from "./chunk-BCMPSLSG.js";
|
|
5
|
+
import {
|
|
6
|
+
slugify
|
|
7
|
+
} from "./chunk-V46BHM2U.js";
|
|
8
|
+
|
|
9
|
+
// src/Form/Form.tsx
|
|
10
|
+
import { useEffect as useEffect2 } from "react";
|
|
11
|
+
import { useForm } from "react-hook-form";
|
|
12
|
+
import cn2 from "classnames";
|
|
13
|
+
|
|
14
|
+
// src/Form/subcomponents/FormDebugViewer.tsx
|
|
15
|
+
import { useEffect, useState } from "react";
|
|
16
|
+
import { FaTimes } from "react-icons/fa";
|
|
17
|
+
import { FaBug } from "react-icons/fa6";
|
|
18
|
+
import cn from "classnames";
|
|
19
|
+
import Button from "@fuf-stack/pixels/Button";
|
|
20
|
+
import Card from "@fuf-stack/pixels/Card";
|
|
21
|
+
import useLocalStorage from "@fuf-stack/pixels/hooks/useLocalStorage";
|
|
22
|
+
import Json from "@fuf-stack/pixels/Json";
|
|
23
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
24
|
+
var LOCALSTORAGE_DEBUG_KEY = "uniform:form-debug-enabled";
|
|
25
|
+
var FormDebugViewer = ({ className = void 0 }) => {
|
|
26
|
+
const {
|
|
27
|
+
watch,
|
|
28
|
+
formState: { dirtyFields, isValid, isSubmitting },
|
|
29
|
+
validation
|
|
30
|
+
} = useFormContext();
|
|
31
|
+
const [debug, setDebug] = useLocalStorage(LOCALSTORAGE_DEBUG_KEY, false);
|
|
32
|
+
const [validationErrors, setValidationErrors] = useState(null);
|
|
33
|
+
const formValues = watch();
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const updateValidationErrors = async () => {
|
|
36
|
+
if (validation) {
|
|
37
|
+
const validateResult = await validation?.validateAsync(formValues);
|
|
38
|
+
setValidationErrors(validateResult?.errors);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
updateValidationErrors();
|
|
42
|
+
}, [JSON.stringify(formValues)]);
|
|
43
|
+
if (!debug) {
|
|
44
|
+
return /* @__PURE__ */ jsx(
|
|
45
|
+
Button,
|
|
46
|
+
{
|
|
47
|
+
ariaLabel: "Enable form debug mode",
|
|
48
|
+
onClick: () => setDebug(!debug),
|
|
49
|
+
className: "absolute bottom-2.5 right-2.5 w-5 text-default-400",
|
|
50
|
+
variant: "light",
|
|
51
|
+
icon: /* @__PURE__ */ jsx(FaBug, {})
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
Card,
|
|
57
|
+
{
|
|
58
|
+
className: cn(className),
|
|
59
|
+
header: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-row justify-between", children: [
|
|
60
|
+
/* @__PURE__ */ jsx("span", { className: "text-lg", children: "Debug Mode" }),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
Button,
|
|
63
|
+
{
|
|
64
|
+
icon: /* @__PURE__ */ jsx(FaTimes, { className: "text-danger" }),
|
|
65
|
+
onClick: () => setDebug(false),
|
|
66
|
+
size: "sm",
|
|
67
|
+
variant: "flat"
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] }),
|
|
71
|
+
children: /* @__PURE__ */ jsx(
|
|
72
|
+
Json,
|
|
73
|
+
{
|
|
74
|
+
value: {
|
|
75
|
+
values: formValues,
|
|
76
|
+
errors: validationErrors,
|
|
77
|
+
dirtyFields,
|
|
78
|
+
isValid,
|
|
79
|
+
isSubmitting
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
var FormDebugViewer_default = FormDebugViewer;
|
|
87
|
+
|
|
88
|
+
// src/Form/Form.tsx
|
|
89
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
90
|
+
var removeNullishFields = (obj) => {
|
|
91
|
+
return JSON.parse(
|
|
92
|
+
JSON.stringify(obj, (_key, value) => {
|
|
93
|
+
return value === null ? void 0 : value;
|
|
94
|
+
})
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
var Form = ({
|
|
98
|
+
children,
|
|
99
|
+
className = void 0,
|
|
100
|
+
initialValues = void 0,
|
|
101
|
+
name = void 0,
|
|
102
|
+
onSubmit,
|
|
103
|
+
testId = void 0,
|
|
104
|
+
validation = void 0,
|
|
105
|
+
validationTrigger = "all"
|
|
106
|
+
}) => {
|
|
107
|
+
const methods = useForm(
|
|
108
|
+
validation ? {
|
|
109
|
+
defaultValues: initialValues,
|
|
110
|
+
resolver: async (values) => {
|
|
111
|
+
const { data, errors, ...rest } = await validation.validateAsync(
|
|
112
|
+
removeNullishFields(values)
|
|
113
|
+
);
|
|
114
|
+
return { values: data || {}, errors: errors || {}, ...rest };
|
|
115
|
+
},
|
|
116
|
+
// set rhf mode
|
|
117
|
+
// see: https://react-hook-form.com/docs/useform#mode
|
|
118
|
+
mode: validationTrigger === "all-instant" ? "all" : validationTrigger
|
|
119
|
+
} : {
|
|
120
|
+
defaultValues: initialValues
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
useEffect2(
|
|
124
|
+
() => {
|
|
125
|
+
if (validationTrigger === "all-instant") {
|
|
126
|
+
methods.trigger();
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
130
|
+
[validationTrigger]
|
|
131
|
+
);
|
|
132
|
+
return (
|
|
133
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
134
|
+
/* @__PURE__ */ jsx2(FormContext_default, { ...methods, validation, children: /* @__PURE__ */ jsxs2("div", { className: "flex w-full flex-row justify-between gap-6", children: [
|
|
135
|
+
/* @__PURE__ */ jsx2(
|
|
136
|
+
"form",
|
|
137
|
+
{
|
|
138
|
+
className: cn2("flex-grow", className),
|
|
139
|
+
"data-testid": slugify(testId || name || ""),
|
|
140
|
+
name,
|
|
141
|
+
onSubmit: methods.handleSubmit(onSubmit),
|
|
142
|
+
children
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
/* @__PURE__ */ jsx2(FormDebugViewer_default, { className: "w-96 flex-shrink" })
|
|
146
|
+
] }) })
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
var Form_default = Form;
|
|
150
|
+
|
|
151
|
+
// src/Form/index.ts
|
|
152
|
+
var Form_default2 = Form_default;
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
Form_default,
|
|
156
|
+
Form_default2
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=chunk-BQUVQMFA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Form/Form.tsx","../src/Form/subcomponents/FormDebugViewer.tsx","../src/Form/index.ts"],"sourcesContent":["import type { VetoInstance } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\nimport type { FieldValues, SubmitHandler } from 'react-hook-form';\n\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport cn from 'classnames';\n\nimport { slugify } from '../helpers';\nimport FormProvider from './subcomponents/FormContext';\nimport FormDebugViewer from './subcomponents/FormDebugViewer';\n\n/**\n * recursively removes all fields that are null or undefined before\n * the form data is passed to the veto validation function\n */\nexport const removeNullishFields = (obj: Record<string, unknown>) => {\n return JSON.parse(\n JSON.stringify(obj, (_key, value) => {\n return value === null ? undefined : value;\n }),\n );\n};\n\nexport interface FormProps {\n /** form children */\n children: ReactNode | ReactNode[];\n /** CSS class name */\n className?: string | string[];\n /** initial form values */\n initialValues?: FieldValues;\n /** name of the form */\n name?: string;\n /** form submit handler */\n onSubmit: SubmitHandler<FieldValues>;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n /** veto validation schema */\n validation?: VetoInstance;\n /** when the validation should be triggered */\n validationTrigger?:\n | 'onChange'\n | 'onBlur'\n | 'onSubmit'\n | 'onTouched'\n | 'all'\n | 'all-instant';\n}\n\n/**\n * Form component that has to wrap every uniform\n */\nconst Form = ({\n children,\n className = undefined,\n initialValues = undefined,\n name = undefined,\n onSubmit,\n testId = undefined,\n validation = undefined,\n validationTrigger = 'all',\n}: FormProps) => {\n const methods = useForm(\n validation\n ? {\n defaultValues: initialValues,\n resolver: async (values) => {\n const { data, errors, ...rest } = await validation.validateAsync(\n removeNullishFields(values),\n );\n // https://github.com/react-hook-form/resolvers/blob/master/zod/src/zod.ts\n return { values: data || {}, errors: errors || {}, ...rest };\n },\n // set rhf mode\n // see: https://react-hook-form.com/docs/useform#mode\n mode: validationTrigger === 'all-instant' ? 'all' : validationTrigger,\n }\n : {\n defaultValues: initialValues,\n },\n );\n\n useEffect(\n () => {\n if (validationTrigger === 'all-instant') {\n methods.trigger();\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [validationTrigger],\n );\n\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <FormProvider {...methods} validation={validation}>\n <div className=\"flex w-full flex-row justify-between gap-6\">\n <form\n className={cn('flex-grow', className)}\n data-testid={slugify(testId || name || '')}\n name={name}\n onSubmit={methods.handleSubmit(onSubmit)}\n >\n {children}\n </form>\n <FormDebugViewer className=\"w-96 flex-shrink\" />\n </div>\n </FormProvider>\n );\n};\n\nexport default Form;\n","import type { VetoError } from '@fuf-stack/veto';\n\nimport { useEffect, useState } from 'react';\nimport { FaTimes } from 'react-icons/fa';\nimport { FaBug } from 'react-icons/fa6';\n\nimport cn from 'classnames';\n\nimport Button from '@fuf-stack/pixels/Button';\nimport Card from '@fuf-stack/pixels/Card';\nimport useLocalStorage from '@fuf-stack/pixels/hooks/useLocalStorage';\nimport Json from '@fuf-stack/pixels/Json';\n\nimport { useFormContext } from '../../hooks';\n\ninterface FormDebugViewerProps {\n /** CSS class name */\n className?: string;\n}\n\nconst LOCALSTORAGE_DEBUG_KEY = 'uniform:form-debug-enabled';\n\n/** Renders a form debug panel with information about the current form state */\nconst FormDebugViewer = ({ className = undefined }: FormDebugViewerProps) => {\n const {\n watch,\n formState: { dirtyFields, isValid, isSubmitting },\n validation,\n } = useFormContext();\n\n const [debug, setDebug] = useLocalStorage(LOCALSTORAGE_DEBUG_KEY, false);\n\n const [validationErrors, setValidationErrors] = useState<\n VetoError['errors'] | null\n >(null);\n\n const formValues = watch();\n\n useEffect(() => {\n const updateValidationErrors = async () => {\n if (validation) {\n const validateResult = await validation?.validateAsync(formValues);\n setValidationErrors(validateResult?.errors);\n }\n };\n updateValidationErrors();\n }, [JSON.stringify(formValues)]);\n\n if (!debug) {\n return (\n <Button\n ariaLabel=\"Enable form debug mode\"\n onClick={() => setDebug(!debug)}\n className=\"absolute bottom-2.5 right-2.5 w-5 text-default-400\"\n variant=\"light\"\n icon={<FaBug />}\n />\n );\n }\n\n return (\n <Card\n className={cn(className)}\n header={\n <div className=\"flex w-full flex-row justify-between\">\n <span className=\"text-lg\">Debug Mode</span>\n <Button\n icon={<FaTimes className=\"text-danger\" />}\n onClick={() => setDebug(false)}\n size=\"sm\"\n variant=\"flat\"\n />\n </div>\n }\n >\n <Json\n value={{\n values: formValues,\n errors: validationErrors,\n dirtyFields,\n isValid,\n isSubmitting,\n }}\n />\n </Card>\n );\n};\nexport default FormDebugViewer;\n","import Form from './Form';\n\nexport type { FormProps } from './Form';\n\nexport { Form };\n\nexport default Form;\n"],"mappings":"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","names":["useEffect","cn","jsx","jsxs","useEffect","cn","Form_default"]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkWQRM7G4Ccjs = require('./chunk-WQRM7G4C.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkBBB4FEY6cjs = require('./chunk-BBB4FEY6.cjs');
|
|
8
|
+
|
|
9
|
+
// src/Form/Form.tsx
|
|
10
|
+
var _react = require('react');
|
|
11
|
+
var _reacthookform = require('react-hook-form');
|
|
12
|
+
var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames);
|
|
13
|
+
|
|
14
|
+
// src/Form/subcomponents/FormDebugViewer.tsx
|
|
15
|
+
|
|
16
|
+
var _fa = require('react-icons/fa');
|
|
17
|
+
var _fa6 = require('react-icons/fa6');
|
|
18
|
+
|
|
19
|
+
var _Button = require('@fuf-stack/pixels/Button'); var _Button2 = _interopRequireDefault(_Button);
|
|
20
|
+
var _Card = require('@fuf-stack/pixels/Card'); var _Card2 = _interopRequireDefault(_Card);
|
|
21
|
+
var _useLocalStorage = require('@fuf-stack/pixels/hooks/useLocalStorage'); var _useLocalStorage2 = _interopRequireDefault(_useLocalStorage);
|
|
22
|
+
var _Json = require('@fuf-stack/pixels/Json'); var _Json2 = _interopRequireDefault(_Json);
|
|
23
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
24
|
+
var LOCALSTORAGE_DEBUG_KEY = "uniform:form-debug-enabled";
|
|
25
|
+
var FormDebugViewer = ({ className = void 0 }) => {
|
|
26
|
+
const {
|
|
27
|
+
watch,
|
|
28
|
+
formState: { dirtyFields, isValid, isSubmitting },
|
|
29
|
+
validation
|
|
30
|
+
} = _chunkWQRM7G4Ccjs.useFormContext.call(void 0, );
|
|
31
|
+
const [debug, setDebug] = _useLocalStorage2.default.call(void 0, LOCALSTORAGE_DEBUG_KEY, false);
|
|
32
|
+
const [validationErrors, setValidationErrors] = _react.useState.call(void 0, null);
|
|
33
|
+
const formValues = watch();
|
|
34
|
+
_react.useEffect.call(void 0, () => {
|
|
35
|
+
const updateValidationErrors = async () => {
|
|
36
|
+
if (validation) {
|
|
37
|
+
const validateResult = await _optionalChain([validation, 'optionalAccess', _ => _.validateAsync, 'call', _2 => _2(formValues)]);
|
|
38
|
+
setValidationErrors(_optionalChain([validateResult, 'optionalAccess', _3 => _3.errors]));
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
updateValidationErrors();
|
|
42
|
+
}, [JSON.stringify(formValues)]);
|
|
43
|
+
if (!debug) {
|
|
44
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
45
|
+
_Button2.default,
|
|
46
|
+
{
|
|
47
|
+
ariaLabel: "Enable form debug mode",
|
|
48
|
+
onClick: () => setDebug(!debug),
|
|
49
|
+
className: "absolute bottom-2.5 right-2.5 w-5 text-default-400",
|
|
50
|
+
variant: "light",
|
|
51
|
+
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _fa6.FaBug, {})
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
56
|
+
_Card2.default,
|
|
57
|
+
{
|
|
58
|
+
className: _classnames2.default.call(void 0, className),
|
|
59
|
+
header: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between", children: [
|
|
60
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-lg", children: "Debug Mode" }),
|
|
61
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
62
|
+
_Button2.default,
|
|
63
|
+
{
|
|
64
|
+
icon: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _fa.FaTimes, { className: "text-danger" }),
|
|
65
|
+
onClick: () => setDebug(false),
|
|
66
|
+
size: "sm",
|
|
67
|
+
variant: "flat"
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
] }),
|
|
71
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
72
|
+
_Json2.default,
|
|
73
|
+
{
|
|
74
|
+
value: {
|
|
75
|
+
values: formValues,
|
|
76
|
+
errors: validationErrors,
|
|
77
|
+
dirtyFields,
|
|
78
|
+
isValid,
|
|
79
|
+
isSubmitting
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
var FormDebugViewer_default = FormDebugViewer;
|
|
87
|
+
|
|
88
|
+
// src/Form/Form.tsx
|
|
89
|
+
|
|
90
|
+
var removeNullishFields = (obj) => {
|
|
91
|
+
return JSON.parse(
|
|
92
|
+
JSON.stringify(obj, (_key, value) => {
|
|
93
|
+
return value === null ? void 0 : value;
|
|
94
|
+
})
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
var Form = ({
|
|
98
|
+
children,
|
|
99
|
+
className = void 0,
|
|
100
|
+
initialValues = void 0,
|
|
101
|
+
name = void 0,
|
|
102
|
+
onSubmit,
|
|
103
|
+
testId = void 0,
|
|
104
|
+
validation = void 0,
|
|
105
|
+
validationTrigger = "all"
|
|
106
|
+
}) => {
|
|
107
|
+
const methods = _reacthookform.useForm.call(void 0,
|
|
108
|
+
validation ? {
|
|
109
|
+
defaultValues: initialValues,
|
|
110
|
+
resolver: async (values) => {
|
|
111
|
+
const { data, errors, ...rest } = await validation.validateAsync(
|
|
112
|
+
removeNullishFields(values)
|
|
113
|
+
);
|
|
114
|
+
return { values: data || {}, errors: errors || {}, ...rest };
|
|
115
|
+
},
|
|
116
|
+
// set rhf mode
|
|
117
|
+
// see: https://react-hook-form.com/docs/useform#mode
|
|
118
|
+
mode: validationTrigger === "all-instant" ? "all" : validationTrigger
|
|
119
|
+
} : {
|
|
120
|
+
defaultValues: initialValues
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
_react.useEffect.call(void 0,
|
|
124
|
+
() => {
|
|
125
|
+
if (validationTrigger === "all-instant") {
|
|
126
|
+
methods.trigger();
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
130
|
+
[validationTrigger]
|
|
131
|
+
);
|
|
132
|
+
return (
|
|
133
|
+
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
134
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkWQRM7G4Ccjs.FormContext_default, { ...methods, validation, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-row justify-between gap-6", children: [
|
|
135
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
136
|
+
"form",
|
|
137
|
+
{
|
|
138
|
+
className: _classnames2.default.call(void 0, "flex-grow", className),
|
|
139
|
+
"data-testid": _chunkBBB4FEY6cjs.slugify.call(void 0, testId || name || ""),
|
|
140
|
+
name,
|
|
141
|
+
onSubmit: methods.handleSubmit(onSubmit),
|
|
142
|
+
children
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormDebugViewer_default, { className: "w-96 flex-shrink" })
|
|
146
|
+
] }) })
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
var Form_default = Form;
|
|
150
|
+
|
|
151
|
+
// src/Form/index.ts
|
|
152
|
+
var Form_default2 = Form_default;
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
exports.Form_default = Form_default; exports.Form_default2 = Form_default2;
|
|
158
|
+
//# sourceMappingURL=chunk-II57W3V2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Form/Form.tsx","../src/Form/subcomponents/FormDebugViewer.tsx","../src/Form/index.ts"],"names":["useEffect","cn","jsx","jsxs","Form_default"],"mappings":"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","sourcesContent":["import type { VetoInstance } from '@fuf-stack/veto';\nimport type { ReactNode } from 'react';\nimport type { FieldValues, SubmitHandler } from 'react-hook-form';\n\nimport { useEffect } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport cn from 'classnames';\n\nimport { slugify } from '../helpers';\nimport FormProvider from './subcomponents/FormContext';\nimport FormDebugViewer from './subcomponents/FormDebugViewer';\n\n/**\n * recursively removes all fields that are null or undefined before\n * the form data is passed to the veto validation function\n */\nexport const removeNullishFields = (obj: Record<string, unknown>) => {\n return JSON.parse(\n JSON.stringify(obj, (_key, value) => {\n return value === null ? undefined : value;\n }),\n );\n};\n\nexport interface FormProps {\n /** form children */\n children: ReactNode | ReactNode[];\n /** CSS class name */\n className?: string | string[];\n /** initial form values */\n initialValues?: FieldValues;\n /** name of the form */\n name?: string;\n /** form submit handler */\n onSubmit: SubmitHandler<FieldValues>;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n /** veto validation schema */\n validation?: VetoInstance;\n /** when the validation should be triggered */\n validationTrigger?:\n | 'onChange'\n | 'onBlur'\n | 'onSubmit'\n | 'onTouched'\n | 'all'\n | 'all-instant';\n}\n\n/**\n * Form component that has to wrap every uniform\n */\nconst Form = ({\n children,\n className = undefined,\n initialValues = undefined,\n name = undefined,\n onSubmit,\n testId = undefined,\n validation = undefined,\n validationTrigger = 'all',\n}: FormProps) => {\n const methods = useForm(\n validation\n ? {\n defaultValues: initialValues,\n resolver: async (values) => {\n const { data, errors, ...rest } = await validation.validateAsync(\n removeNullishFields(values),\n );\n // https://github.com/react-hook-form/resolvers/blob/master/zod/src/zod.ts\n return { values: data || {}, errors: errors || {}, ...rest };\n },\n // set rhf mode\n // see: https://react-hook-form.com/docs/useform#mode\n mode: validationTrigger === 'all-instant' ? 'all' : validationTrigger,\n }\n : {\n defaultValues: initialValues,\n },\n );\n\n useEffect(\n () => {\n if (validationTrigger === 'all-instant') {\n methods.trigger();\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [validationTrigger],\n );\n\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <FormProvider {...methods} validation={validation}>\n <div className=\"flex w-full flex-row justify-between gap-6\">\n <form\n className={cn('flex-grow', className)}\n data-testid={slugify(testId || name || '')}\n name={name}\n onSubmit={methods.handleSubmit(onSubmit)}\n >\n {children}\n </form>\n <FormDebugViewer className=\"w-96 flex-shrink\" />\n </div>\n </FormProvider>\n );\n};\n\nexport default Form;\n","import type { VetoError } from '@fuf-stack/veto';\n\nimport { useEffect, useState } from 'react';\nimport { FaTimes } from 'react-icons/fa';\nimport { FaBug } from 'react-icons/fa6';\n\nimport cn from 'classnames';\n\nimport Button from '@fuf-stack/pixels/Button';\nimport Card from '@fuf-stack/pixels/Card';\nimport useLocalStorage from '@fuf-stack/pixels/hooks/useLocalStorage';\nimport Json from '@fuf-stack/pixels/Json';\n\nimport { useFormContext } from '../../hooks';\n\ninterface FormDebugViewerProps {\n /** CSS class name */\n className?: string;\n}\n\nconst LOCALSTORAGE_DEBUG_KEY = 'uniform:form-debug-enabled';\n\n/** Renders a form debug panel with information about the current form state */\nconst FormDebugViewer = ({ className = undefined }: FormDebugViewerProps) => {\n const {\n watch,\n formState: { dirtyFields, isValid, isSubmitting },\n validation,\n } = useFormContext();\n\n const [debug, setDebug] = useLocalStorage(LOCALSTORAGE_DEBUG_KEY, false);\n\n const [validationErrors, setValidationErrors] = useState<\n VetoError['errors'] | null\n >(null);\n\n const formValues = watch();\n\n useEffect(() => {\n const updateValidationErrors = async () => {\n if (validation) {\n const validateResult = await validation?.validateAsync(formValues);\n setValidationErrors(validateResult?.errors);\n }\n };\n updateValidationErrors();\n }, [JSON.stringify(formValues)]);\n\n if (!debug) {\n return (\n <Button\n ariaLabel=\"Enable form debug mode\"\n onClick={() => setDebug(!debug)}\n className=\"absolute bottom-2.5 right-2.5 w-5 text-default-400\"\n variant=\"light\"\n icon={<FaBug />}\n />\n );\n }\n\n return (\n <Card\n className={cn(className)}\n header={\n <div className=\"flex w-full flex-row justify-between\">\n <span className=\"text-lg\">Debug Mode</span>\n <Button\n icon={<FaTimes className=\"text-danger\" />}\n onClick={() => setDebug(false)}\n size=\"sm\"\n variant=\"flat\"\n />\n </div>\n }\n >\n <Json\n value={{\n values: formValues,\n errors: validationErrors,\n dirtyFields,\n isValid,\n isSubmitting,\n }}\n />\n </Card>\n );\n};\nexport default FormDebugViewer;\n","import Form from './Form';\n\nexport type { FormProps } from './Form';\n\nexport { Form };\n\nexport default Form;\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/Grid/Grid.tsx
|
|
2
|
+
var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames);
|
|
3
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
4
|
+
var Grid = ({
|
|
5
|
+
children = null,
|
|
6
|
+
className = void 0,
|
|
7
|
+
testId = void 0
|
|
8
|
+
}) => {
|
|
9
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: _classnames2.default.call(void 0, "grid gap-6", className), "data-testid": testId, children });
|
|
10
|
+
};
|
|
11
|
+
var Grid_default = Grid;
|
|
12
|
+
|
|
13
|
+
// src/Grid/index.ts
|
|
14
|
+
var Grid_default2 = Grid_default;
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
exports.Grid_default = Grid_default; exports.Grid_default2 = Grid_default2;
|
|
20
|
+
//# sourceMappingURL=chunk-ZPFKVKGV.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Grid/Grid.tsx","../src/Grid/index.ts"],"names":["Grid_default"],"mappings":";AAEA,OAAO,QAAQ;AAoBX;AANJ,IAAM,OAAO,CAAC;AAAA,EACZ,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,SAAS;AACX,MAAiB;AACf,SACE,oBAAC,SAAI,WAAW,GAAG,cAAc,SAAS,GAAG,eAAa,QACvD,UACH;AAEJ;AAEA,IAAO,eAAQ;;;ACtBf,IAAOA,gBAAQ","sourcesContent":["import type { ReactNode } from 'react';\n\nimport cn from 'classnames';\n\nexport interface GridProps {\n /** child components */\n children?: ReactNode;\n /** CSS class name */\n className?: string;\n /** HTML data-testid attribute used in e2e tests */\n testId?: string;\n}\n\n/**\n * Defines the default grid for form components\n */\nconst Grid = ({\n children = null,\n className = undefined,\n testId = undefined,\n}: GridProps) => {\n return (\n <div className={cn('grid gap-6', className)} data-testid={testId}>\n {children}\n </div>\n );\n};\n\nexport default Grid;\n","import Grid from './Grid';\n\nexport type { GridProps } from './Grid';\n\nexport { Grid };\n\nexport default Grid;\n"]}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
var _chunkII57W3V2cjs = require('./chunk-II57W3V2.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
var _chunkZPFKVKGVcjs = require('./chunk-ZPFKVKGV.cjs');
|
|
7
|
+
require('./chunk-WQRM7G4C.cjs');
|
|
8
|
+
require('./chunk-BBB4FEY6.cjs');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.Form = _chunkII57W3V2cjs.Form_default; exports.Grid = _chunkZPFKVKGVcjs.Grid_default;
|
|
13
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":""}
|
package/dist/index.d.cts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Form_default
|
|
3
|
+
} from "./chunk-BQUVQMFA.js";
|
|
4
|
+
import {
|
|
5
|
+
Grid_default
|
|
6
|
+
} from "./chunk-4MEKDDB2.js";
|
|
7
|
+
import "./chunk-BCMPSLSG.js";
|
|
8
|
+
import "./chunk-V46BHM2U.js";
|
|
9
|
+
export {
|
|
10
|
+
Form_default as Form,
|
|
11
|
+
Grid_default as Grid
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuf-stack/uniform",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "fuf react form library",
|
|
5
5
|
"author": "Hannes Tiede",
|
|
6
6
|
"homepage": "https://github.com/fuf-stack/uniform#readme",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.cjs",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
9
12
|
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
},
|
|
10
18
|
"./Form": {
|
|
11
19
|
"import": "./dist/Form/index.js",
|
|
12
20
|
"require": "./dist/Form/index.cjs",
|
|
@@ -17,11 +25,6 @@
|
|
|
17
25
|
"require": "./dist/Grid/index.cjs",
|
|
18
26
|
"types": "./dist/Grid/index.d.ts"
|
|
19
27
|
},
|
|
20
|
-
"./SubmitButton": {
|
|
21
|
-
"import": "./dist/SubmitButton/index.js",
|
|
22
|
-
"require": "./dist/SubmitButton/index.cjs",
|
|
23
|
-
"types": "./dist/SubmitButton/index.d.ts"
|
|
24
|
-
},
|
|
25
28
|
"./helpers": {
|
|
26
29
|
"import": "./dist/helpers/index.js",
|
|
27
30
|
"require": "./dist/helpers/index.cjs",
|
|
@@ -41,6 +44,11 @@
|
|
|
41
44
|
"import": "./dist/partials/FieldValidationError/index.js",
|
|
42
45
|
"require": "./dist/partials/FieldValidationError/index.cjs",
|
|
43
46
|
"types": "./dist/partials/FieldValidationError/index.d.ts"
|
|
47
|
+
},
|
|
48
|
+
"./SubmitButton": {
|
|
49
|
+
"import": "./dist/SubmitButton/index.js",
|
|
50
|
+
"require": "./dist/SubmitButton/index.cjs",
|
|
51
|
+
"types": "./dist/SubmitButton/index.d.ts"
|
|
44
52
|
}
|
|
45
53
|
},
|
|
46
54
|
"files": [
|
|
@@ -88,8 +96,8 @@
|
|
|
88
96
|
"@types/react-dom": "18.2.22",
|
|
89
97
|
"@types/slug": "5.0.8",
|
|
90
98
|
"@repo/storybook-config": "0.0.1",
|
|
91
|
-
"@repo/
|
|
92
|
-
"@repo/
|
|
99
|
+
"@repo/tailwind-config": "0.0.1",
|
|
100
|
+
"@repo/vite-config": "0.0.1"
|
|
93
101
|
},
|
|
94
102
|
"scripts": {
|
|
95
103
|
"test": "vitest ./src"
|