@pindoba/react-tanstack-form 0.0.0-alpha-20260617191010
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/LICENSE +12 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +8 -0
- package/dist/src/FormCheckbox.d.ts +25 -0
- package/dist/src/FormCheckbox.d.ts.map +1 -0
- package/dist/src/FormCheckbox.js +26 -0
- package/dist/src/FormCheckbox.js.map +1 -0
- package/dist/src/FormField.d.ts +34 -0
- package/dist/src/FormField.d.ts.map +1 -0
- package/dist/src/FormField.js +28 -0
- package/dist/src/FormField.js.map +1 -0
- package/dist/src/FormInput.d.ts +26 -0
- package/dist/src/FormInput.d.ts.map +1 -0
- package/dist/src/FormInput.js +27 -0
- package/dist/src/FormInput.js.map +1 -0
- package/dist/src/FormSelect.d.ts +28 -0
- package/dist/src/FormSelect.d.ts.map +1 -0
- package/dist/src/FormSelect.js +29 -0
- package/dist/src/FormSelect.js.map +1 -0
- package/dist/src/FormSubmit.d.ts +36 -0
- package/dist/src/FormSubmit.d.ts.map +1 -0
- package/dist/src/FormSubmit.js +34 -0
- package/dist/src/FormSubmit.js.map +1 -0
- package/dist/src/field-errors.d.ts +2 -0
- package/dist/src/field-errors.js +2 -0
- package/dist/src/types.d.ts +38 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Copyright 2025 Eduardo Lopes
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
8
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
9
|
+
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
10
|
+
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
11
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
12
|
+
DEALINGS IN THE SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AnyFieldApi, AnyFormApi, FormFieldErrorMode, FormFieldOwnProps } from "./src/types.js";
|
|
2
|
+
import { FormField, FormFieldProps } from "./src/FormField.js";
|
|
3
|
+
import { FormInput, FormInputProps } from "./src/FormInput.js";
|
|
4
|
+
import { FormSelect, FormSelectProps } from "./src/FormSelect.js";
|
|
5
|
+
import { FormCheckbox, FormCheckboxProps } from "./src/FormCheckbox.js";
|
|
6
|
+
import { FormSubmit, FormSubmitProps } from "./src/FormSubmit.js";
|
|
7
|
+
import { getVisibleErrors, normalizeErrors } from "./src/field-errors.js";
|
|
8
|
+
import { useForm, useStore } from "@tanstack/react-form";
|
|
9
|
+
export { type AnyFieldApi, type AnyFormApi, FormCheckbox, type FormCheckboxProps, FormField, type FormFieldErrorMode, type FormFieldOwnProps, type FormFieldProps, FormInput, type FormInputProps, FormSelect, type FormSelectProps, FormSubmit, type FormSubmitProps, getVisibleErrors, normalizeErrors, useForm, useStore };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { getVisibleErrors, normalizeErrors } from "./src/field-errors.js";
|
|
2
|
+
import { FormField } from "./src/FormField.js";
|
|
3
|
+
import { FormInput } from "./src/FormInput.js";
|
|
4
|
+
import { FormSelect } from "./src/FormSelect.js";
|
|
5
|
+
import { FormCheckbox } from "./src/FormCheckbox.js";
|
|
6
|
+
import { FormSubmit } from "./src/FormSubmit.js";
|
|
7
|
+
import { useForm, useStore } from "@tanstack/react-form";
|
|
8
|
+
export { FormCheckbox, FormField, FormInput, FormSelect, FormSubmit, getVisibleErrors, normalizeErrors, useForm, useStore };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AnyFormApi, FormFieldOwnProps } from "./types.js";
|
|
2
|
+
import { FieldSize } from "@pindoba/core-field";
|
|
3
|
+
import { JSX, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/FormCheckbox.d.ts
|
|
6
|
+
type FormCheckboxProps = Omit<FormFieldOwnProps, "size"> & {
|
|
7
|
+
/** The TanStack form instance returned by `useForm(...)`. */form: AnyFormApi; /** Field name (a boolean key of the form's data). */
|
|
8
|
+
name: string; /** Inline text/content rendered beside the checkbox. */
|
|
9
|
+
children?: ReactNode; /** Size variant. Checkbox supports `sm`/`md`/`lg` (no `xs`). */
|
|
10
|
+
size?: Exclude<FieldSize, "xs">;
|
|
11
|
+
};
|
|
12
|
+
/** FormCheckbox — a `<Checkbox>` bound to a boolean TanStack form field. */
|
|
13
|
+
declare function FormCheckbox({
|
|
14
|
+
form,
|
|
15
|
+
name,
|
|
16
|
+
children,
|
|
17
|
+
size,
|
|
18
|
+
...fieldProps
|
|
19
|
+
}: FormCheckboxProps): JSX.Element;
|
|
20
|
+
declare namespace FormCheckbox {
|
|
21
|
+
var displayName: string;
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { FormCheckbox, FormCheckboxProps };
|
|
25
|
+
//# sourceMappingURL=FormCheckbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormCheckbox.d.ts","names":[],"sources":["../../src/FormCheckbox.tsx"],"mappings":";;;;;KAMY,iBAAA,GAAoB,IAAA,CAAK,iBAAA;+DAEnC,IAAA,EAAM,UAAA,EAFqB;EAI3B,IAAA,UAJmC;EAMnC,QAAA,GAAW,SAAA,EAJL;EAMN,IAAA,GAAO,OAAA,CAAQ,SAAA;AAAA;;iBAID,YAAA;EACd,IAAA;EACA,IAAA;EACA,QAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,iBAAA,GAAoB,GAAA,CAAI,OAAA;AAAA,kBANX,YAAA;EAAA,IAAY,WAAA;AAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { FormField } from "./FormField.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import Checkbox from "@pindoba/react-checkbox";
|
|
4
|
+
//#region src/FormCheckbox.tsx
|
|
5
|
+
/** FormCheckbox — a `<Checkbox>` bound to a boolean TanStack form field. */
|
|
6
|
+
function FormCheckbox({ form, name, children, size, ...fieldProps }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(FormField, {
|
|
8
|
+
form,
|
|
9
|
+
name,
|
|
10
|
+
size,
|
|
11
|
+
...fieldProps,
|
|
12
|
+
control: (props, field) => /* @__PURE__ */ jsx(Checkbox, {
|
|
13
|
+
...props,
|
|
14
|
+
size,
|
|
15
|
+
checked: Boolean(field.state.value),
|
|
16
|
+
onChange: (event) => field.handleChange(event.target.checked),
|
|
17
|
+
onBlur: () => field.handleBlur(),
|
|
18
|
+
children
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
FormCheckbox.displayName = "FormCheckbox";
|
|
23
|
+
//#endregion
|
|
24
|
+
export { FormCheckbox };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=FormCheckbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormCheckbox.js","names":[],"sources":["../../src/FormCheckbox.tsx"],"sourcesContent":["import type { FieldSize } from \"@pindoba/core-field\";\nimport Checkbox from \"@pindoba/react-checkbox\";\nimport type { JSX, ReactNode } from \"react\";\nimport { FormField } from \"./FormField\";\nimport type { AnyFormApi, FormFieldOwnProps } from \"./types\";\n\nexport type FormCheckboxProps = Omit<FormFieldOwnProps, \"size\"> & {\n /** The TanStack form instance returned by `useForm(...)`. */\n form: AnyFormApi;\n /** Field name (a boolean key of the form's data). */\n name: string;\n /** Inline text/content rendered beside the checkbox. */\n children?: ReactNode;\n /** Size variant. Checkbox supports `sm`/`md`/`lg` (no `xs`). */\n size?: Exclude<FieldSize, \"xs\">;\n};\n\n/** FormCheckbox — a `<Checkbox>` bound to a boolean TanStack form field. */\nexport function FormCheckbox({\n form,\n name,\n children,\n size,\n ...fieldProps\n}: FormCheckboxProps): JSX.Element {\n return (\n <FormField\n form={form}\n name={name}\n size={size}\n {...fieldProps}\n control={(props, field) => (\n <Checkbox\n {...props}\n size={size}\n checked={Boolean(field.state.value)}\n onChange={(event) => field.handleChange(event.target.checked)}\n onBlur={() => field.handleBlur()}\n >\n {children}\n </Checkbox>\n )}\n />\n );\n}\n\nFormCheckbox.displayName = \"FormCheckbox\";\n"],"mappings":";;;;;AAkBA,SAAgB,aAAa,EAC3B,MACA,MACA,UACA,MACA,GAAG,cAC8B;CACjC,OACE,oBAAC,WAAD;EACQ;EACA;EACA;EACN,GAAI;EACJ,UAAU,OAAO,UACf,oBAAC,UAAD;GACE,GAAI;GACE;GACN,SAAS,QAAQ,MAAM,MAAM,KAAK;GAClC,WAAW,UAAU,MAAM,aAAa,MAAM,OAAO,OAAO;GAC5D,cAAc,MAAM,WAAW;GAE9B;EACO,CAAA;CAEb,CAAA;AAEL;AAEA,aAAa,cAAc"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AnyFieldApi, AnyFormApi, FormFieldOwnProps } from "./types.js";
|
|
2
|
+
import { FieldControlProps } from "@pindoba/core-field";
|
|
3
|
+
import { JSX, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/FormField.d.ts
|
|
6
|
+
type FormFieldProps = FormFieldOwnProps & {
|
|
7
|
+
/** The TanStack form instance returned by `useForm(...)`. */form: AnyFormApi; /** Field name (a key of the form's data). */
|
|
8
|
+
name: string;
|
|
9
|
+
/**
|
|
10
|
+
* Render-prop for the control. Receives the props bag to spread onto the
|
|
11
|
+
* control plus the raw TanStack field API for value/handler binding.
|
|
12
|
+
*/
|
|
13
|
+
control: (controlProps: FieldControlProps, field: AnyFieldApi) => ReactNode;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* FormField. Binds a TanStack React Form field to the presentational `<Field>`
|
|
17
|
+
* wrapper. Errors are surfaced through the shared `getVisibleErrors` helper
|
|
18
|
+
* (same visibility logic as the Svelte/Astro blocks); the consumer supplies the
|
|
19
|
+
* control via the `control` render-prop, which receives the Field's `controlProps`
|
|
20
|
+
* bag plus the raw `field` API.
|
|
21
|
+
*/
|
|
22
|
+
declare function FormField({
|
|
23
|
+
form,
|
|
24
|
+
name,
|
|
25
|
+
control,
|
|
26
|
+
errorMode,
|
|
27
|
+
...fieldProps
|
|
28
|
+
}: FormFieldProps): JSX.Element;
|
|
29
|
+
declare namespace FormField {
|
|
30
|
+
var displayName: string;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { FormField, FormFieldProps };
|
|
34
|
+
//# sourceMappingURL=FormField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormField.d.ts","names":[],"sources":["../../src/FormField.tsx"],"mappings":";;;;;KAOY,cAAA,GAAiB,iBAAA;+DAE3B,IAAA,EAAM,UAAA,EAFkB;EAIxB,IAAA;EAJ2B;;;;EAS3B,OAAA,GAAU,YAAA,EAAc,iBAAA,EAAmB,KAAA,EAAO,WAAA,KAAgB,SAAA;AAAA;;;;;;;;iBAUpD,SAAA;EACd,IAAA;EACA,IAAA;EACA,OAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,cAAA,GAAiB,GAAA,CAAI,OAAA;AAAA,kBANR,SAAA;EAAA,IAAS,WAAA;AAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { getVisibleErrors } from "./field-errors.js";
|
|
2
|
+
import { Field } from "@tanstack/react-form";
|
|
3
|
+
import Field$1 from "@pindoba/react-field";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/FormField.tsx
|
|
6
|
+
/**
|
|
7
|
+
* FormField. Binds a TanStack React Form field to the presentational `<Field>`
|
|
8
|
+
* wrapper. Errors are surfaced through the shared `getVisibleErrors` helper
|
|
9
|
+
* (same visibility logic as the Svelte/Astro blocks); the consumer supplies the
|
|
10
|
+
* control via the `control` render-prop, which receives the Field's `controlProps`
|
|
11
|
+
* bag plus the raw `field` API.
|
|
12
|
+
*/
|
|
13
|
+
function FormField({ form, name, control, errorMode = "touched", ...fieldProps }) {
|
|
14
|
+
return /* @__PURE__ */ jsx(Field, {
|
|
15
|
+
form,
|
|
16
|
+
name,
|
|
17
|
+
children: (field) => /* @__PURE__ */ jsx(Field$1, {
|
|
18
|
+
...fieldProps,
|
|
19
|
+
error: getVisibleErrors(field, errorMode),
|
|
20
|
+
control: (controlProps) => control(controlProps, field)
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
FormField.displayName = "FormField";
|
|
25
|
+
//#endregion
|
|
26
|
+
export { FormField };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=FormField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormField.js","names":["TanStackField","Field"],"sources":["../../src/FormField.tsx"],"sourcesContent":["import type { FieldControlProps } from \"@pindoba/core-field\";\nimport Field from \"@pindoba/react-field\";\nimport { Field as TanStackField } from \"@tanstack/react-form\";\nimport type { JSX, ReactNode } from \"react\";\nimport { getVisibleErrors } from \"./field-errors\";\nimport type { AnyFieldApi, AnyFormApi, FormFieldOwnProps } from \"./types\";\n\nexport type FormFieldProps = FormFieldOwnProps & {\n /** The TanStack form instance returned by `useForm(...)`. */\n form: AnyFormApi;\n /** Field name (a key of the form's data). */\n name: string;\n /**\n * Render-prop for the control. Receives the props bag to spread onto the\n * control plus the raw TanStack field API for value/handler binding.\n */\n control: (controlProps: FieldControlProps, field: AnyFieldApi) => ReactNode;\n};\n\n/**\n * FormField. Binds a TanStack React Form field to the presentational `<Field>`\n * wrapper. Errors are surfaced through the shared `getVisibleErrors` helper\n * (same visibility logic as the Svelte/Astro blocks); the consumer supplies the\n * control via the `control` render-prop, which receives the Field's `controlProps`\n * bag plus the raw `field` API.\n */\nexport function FormField({\n form,\n name,\n control,\n errorMode = \"touched\",\n ...fieldProps\n}: FormFieldProps): JSX.Element {\n return (\n <TanStackField form={form} name={name}>\n {(field) => (\n <Field\n {...fieldProps}\n error={getVisibleErrors(field, errorMode)}\n control={(controlProps) => control(controlProps, field)}\n />\n )}\n </TanStackField>\n );\n}\n\nFormField.displayName = \"FormField\";\n"],"mappings":";;;;;;;;;;;;AA0BA,SAAgB,UAAU,EACxB,MACA,MACA,SACA,YAAY,WACZ,GAAG,cAC2B;CAC9B,OACE,oBAACA,OAAD;EAAqB;EAAY;aAC7B,UACA,oBAACC,SAAD;GACE,GAAI;GACJ,OAAO,iBAAiB,OAAO,SAAS;GACxC,UAAU,iBAAiB,QAAQ,cAAc,KAAK;EACvD,CAAA;CAEU,CAAA;AAEnB;AAEA,UAAU,cAAc"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AnyFormApi, FormFieldOwnProps } from "./types.js";
|
|
2
|
+
import { InputProps } from "@pindoba/react-input";
|
|
3
|
+
import { JSX } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/FormInput.d.ts
|
|
6
|
+
type FormInputProps = FormFieldOwnProps & {
|
|
7
|
+
/** The TanStack form instance returned by `useForm(...)`. */form: AnyFormApi; /** Field name (a key of the form's data). */
|
|
8
|
+
name: string; /** HTML input type forwarded to the underlying `<Input>`. */
|
|
9
|
+
type?: InputProps["type"]; /** Placeholder forwarded to the underlying `<Input>`. */
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
};
|
|
12
|
+
/** FormInput — a text `<Input>` bound to a TanStack form field. */
|
|
13
|
+
declare function FormInput({
|
|
14
|
+
form,
|
|
15
|
+
name,
|
|
16
|
+
type,
|
|
17
|
+
placeholder,
|
|
18
|
+
size,
|
|
19
|
+
...fieldProps
|
|
20
|
+
}: FormInputProps): JSX.Element;
|
|
21
|
+
declare namespace FormInput {
|
|
22
|
+
var displayName: string;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { FormInput, FormInputProps };
|
|
26
|
+
//# sourceMappingURL=FormInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormInput.d.ts","names":[],"sources":["../../src/FormInput.tsx"],"mappings":";;;;;KAKY,cAAA,GAAiB,iBAAA;+DAE3B,IAAA,EAAM,UAAA,EAFkB;EAIxB,IAAA,UAJ2B;EAM3B,IAAA,GAAO,UAAA,UAAA;EAEP,WAAA;AAAA;;iBAIc,SAAA;EACd,IAAA;EACA,IAAA;EACA,IAAA;EACA,WAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,cAAA,GAAiB,GAAA,CAAI,OAAA;AAAA,kBAPR,SAAA;EAAA,IAAS,WAAA;AAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { FormField } from "./FormField.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import Input from "@pindoba/react-input";
|
|
4
|
+
//#region src/FormInput.tsx
|
|
5
|
+
/** FormInput — a text `<Input>` bound to a TanStack form field. */
|
|
6
|
+
function FormInput({ form, name, type = "text", placeholder, size, ...fieldProps }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(FormField, {
|
|
8
|
+
form,
|
|
9
|
+
name,
|
|
10
|
+
size,
|
|
11
|
+
...fieldProps,
|
|
12
|
+
control: (props, field) => /* @__PURE__ */ jsx(Input, {
|
|
13
|
+
...props,
|
|
14
|
+
size,
|
|
15
|
+
type,
|
|
16
|
+
placeholder,
|
|
17
|
+
value: String(field.state.value ?? ""),
|
|
18
|
+
onChange: (event) => field.handleChange(event.target.value),
|
|
19
|
+
onBlur: () => field.handleBlur()
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
FormInput.displayName = "FormInput";
|
|
24
|
+
//#endregion
|
|
25
|
+
export { FormInput };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=FormInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormInput.js","names":[],"sources":["../../src/FormInput.tsx"],"sourcesContent":["import Input, { type InputProps } from \"@pindoba/react-input\";\nimport type { JSX } from \"react\";\nimport { FormField } from \"./FormField\";\nimport type { AnyFormApi, FormFieldOwnProps } from \"./types\";\n\nexport type FormInputProps = FormFieldOwnProps & {\n /** The TanStack form instance returned by `useForm(...)`. */\n form: AnyFormApi;\n /** Field name (a key of the form's data). */\n name: string;\n /** HTML input type forwarded to the underlying `<Input>`. */\n type?: InputProps[\"type\"];\n /** Placeholder forwarded to the underlying `<Input>`. */\n placeholder?: string;\n};\n\n/** FormInput — a text `<Input>` bound to a TanStack form field. */\nexport function FormInput({\n form,\n name,\n type = \"text\",\n placeholder,\n size,\n ...fieldProps\n}: FormInputProps): JSX.Element {\n return (\n <FormField\n form={form}\n name={name}\n size={size}\n {...fieldProps}\n control={(props, field) => (\n <Input\n {...props}\n size={size}\n type={type}\n placeholder={placeholder}\n value={String(field.state.value ?? \"\")}\n onChange={(event) => field.handleChange(event.target.value)}\n onBlur={() => field.handleBlur()}\n />\n )}\n />\n );\n}\n\nFormInput.displayName = \"FormInput\";\n"],"mappings":";;;;;AAiBA,SAAgB,UAAU,EACxB,MACA,MACA,OAAO,QACP,aACA,MACA,GAAG,cAC2B;CAC9B,OACE,oBAAC,WAAD;EACQ;EACA;EACA;EACN,GAAI;EACJ,UAAU,OAAO,UACf,oBAAC,OAAD;GACE,GAAI;GACE;GACA;GACO;GACb,OAAO,OAAO,MAAM,MAAM,SAAS,EAAE;GACrC,WAAW,UAAU,MAAM,aAAa,MAAM,OAAO,KAAK;GAC1D,cAAc,MAAM,WAAW;EAChC,CAAA;CAEJ,CAAA;AAEL;AAEA,UAAU,cAAc"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { AnyFormApi, FormFieldOwnProps } from "./types.js";
|
|
2
|
+
import { FieldSize } from "@pindoba/core-field";
|
|
3
|
+
import { JSX } from "react";
|
|
4
|
+
import { ListBoxNodeInput } from "@pindoba/core-listbox";
|
|
5
|
+
|
|
6
|
+
//#region src/FormSelect.d.ts
|
|
7
|
+
type FormSelectProps = Omit<FormFieldOwnProps, "size"> & {
|
|
8
|
+
/** The TanStack form instance returned by `useForm(...)`. */form: AnyFormApi; /** Field name (a key of the form's data holding the selected option key). */
|
|
9
|
+
name: string; /** Options to choose from. */
|
|
10
|
+
items: ListBoxNodeInput[]; /** Placeholder shown when nothing is selected. */
|
|
11
|
+
placeholder?: string; /** Size variant. Select supports `sm`/`md`/`lg` (no `xs`). */
|
|
12
|
+
size?: Exclude<FieldSize, "xs">;
|
|
13
|
+
};
|
|
14
|
+
/** FormSelect — a single-select `<Select>` bound to a TanStack form field. */
|
|
15
|
+
declare function FormSelect({
|
|
16
|
+
form,
|
|
17
|
+
name,
|
|
18
|
+
items,
|
|
19
|
+
placeholder,
|
|
20
|
+
size,
|
|
21
|
+
...fieldProps
|
|
22
|
+
}: FormSelectProps): JSX.Element;
|
|
23
|
+
declare namespace FormSelect {
|
|
24
|
+
var displayName: string;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { FormSelect, FormSelectProps };
|
|
28
|
+
//# sourceMappingURL=FormSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSelect.d.ts","names":[],"sources":["../../src/FormSelect.tsx"],"mappings":";;;;;;KAOY,eAAA,GAAkB,IAAA,CAAK,iBAAA;+DAEjC,IAAA,EAAM,UAAA,EAFmB;EAIzB,IAAA,UAJiC;EAMjC,KAAA,EAAO,gBAAA,IAJD;EAMN,WAAA,WAEe;EAAf,IAAA,GAAO,OAAA,CAAQ,SAAA;AAAA;;iBAID,UAAA;EACd,IAAA;EACA,IAAA;EACA,KAAA;EACA,WAAA;EACA,IAAA;EAAA,GACG;AAAA,GACF,eAAA,GAAkB,GAAA,CAAI,OAAA;AAAA,kBAPT,UAAA;EAAA,IAAU,WAAA;AAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FormField } from "./FormField.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import Select from "@pindoba/react-select";
|
|
4
|
+
//#region src/FormSelect.tsx
|
|
5
|
+
/** FormSelect — a single-select `<Select>` bound to a TanStack form field. */
|
|
6
|
+
function FormSelect({ form, name, items, placeholder, size, ...fieldProps }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(FormField, {
|
|
8
|
+
form,
|
|
9
|
+
name,
|
|
10
|
+
size,
|
|
11
|
+
...fieldProps,
|
|
12
|
+
control: (props, field) => /* @__PURE__ */ jsx(Select, {
|
|
13
|
+
...props,
|
|
14
|
+
size,
|
|
15
|
+
items,
|
|
16
|
+
placeholder,
|
|
17
|
+
value: typeof field.state.value === "string" && field.state.value ? field.state.value : null,
|
|
18
|
+
onValueChange: (next) => field.handleChange(typeof next === "string" ? next : ""),
|
|
19
|
+
onOpenChange: (open) => {
|
|
20
|
+
if (!open) field.handleBlur();
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
FormSelect.displayName = "FormSelect";
|
|
26
|
+
//#endregion
|
|
27
|
+
export { FormSelect };
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=FormSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSelect.js","names":[],"sources":["../../src/FormSelect.tsx"],"sourcesContent":["import type { FieldSize } from \"@pindoba/core-field\";\nimport type { ListBoxNodeInput } from \"@pindoba/core-listbox\";\nimport Select from \"@pindoba/react-select\";\nimport type { JSX } from \"react\";\nimport { FormField } from \"./FormField\";\nimport type { AnyFormApi, FormFieldOwnProps } from \"./types\";\n\nexport type FormSelectProps = Omit<FormFieldOwnProps, \"size\"> & {\n /** The TanStack form instance returned by `useForm(...)`. */\n form: AnyFormApi;\n /** Field name (a key of the form's data holding the selected option key). */\n name: string;\n /** Options to choose from. */\n items: ListBoxNodeInput[];\n /** Placeholder shown when nothing is selected. */\n placeholder?: string;\n /** Size variant. Select supports `sm`/`md`/`lg` (no `xs`). */\n size?: Exclude<FieldSize, \"xs\">;\n};\n\n/** FormSelect — a single-select `<Select>` bound to a TanStack form field. */\nexport function FormSelect({\n form,\n name,\n items,\n placeholder,\n size,\n ...fieldProps\n}: FormSelectProps): JSX.Element {\n return (\n <FormField\n form={form}\n name={name}\n size={size}\n {...fieldProps}\n control={(props, field) => (\n <Select\n {...props}\n size={size}\n items={items}\n placeholder={placeholder}\n value={\n typeof field.state.value === \"string\" && field.state.value\n ? field.state.value\n : null\n }\n onValueChange={(next) =>\n field.handleChange(typeof next === \"string\" ? next : \"\")\n }\n onOpenChange={(open) => {\n // Mark touched when the dropdown closes — so `errorMode=\"touched\"`\n // surfaces a required error after opening and dismissing without\n // picking.\n if (!open) field.handleBlur();\n }}\n />\n )}\n />\n );\n}\n\nFormSelect.displayName = \"FormSelect\";\n"],"mappings":";;;;;AAqBA,SAAgB,WAAW,EACzB,MACA,MACA,OACA,aACA,MACA,GAAG,cAC4B;CAC/B,OACE,oBAAC,WAAD;EACQ;EACA;EACA;EACN,GAAI;EACJ,UAAU,OAAO,UACf,oBAAC,QAAD;GACE,GAAI;GACE;GACC;GACM;GACb,OACE,OAAO,MAAM,MAAM,UAAU,YAAY,MAAM,MAAM,QACjD,MAAM,MAAM,QACZ;GAEN,gBAAgB,SACd,MAAM,aAAa,OAAO,SAAS,WAAW,OAAO,EAAE;GAEzD,eAAe,SAAS;IAItB,IAAI,CAAC,MAAM,MAAM,WAAW;GAC9B;EACD,CAAA;CAEJ,CAAA;AAEL;AAEA,WAAW,cAAc"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { AnyFormApi } from "./types.js";
|
|
2
|
+
import { ButtonProps } from "@pindoba/react-button";
|
|
3
|
+
import { JSX, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/FormSubmit.d.ts
|
|
6
|
+
type FormSubmitProps = {
|
|
7
|
+
/** The TanStack form instance returned by `useForm(...)`. */form: AnyFormApi;
|
|
8
|
+
/**
|
|
9
|
+
* Also disable while the form is invalid (not just while submitting). Off by
|
|
10
|
+
* default — the button stays clickable so submitting an invalid form surfaces
|
|
11
|
+
* its errors instead of leaving the user stuck on a disabled control.
|
|
12
|
+
* @default false
|
|
13
|
+
*/
|
|
14
|
+
disableWhenInvalid?: boolean; /** Emphasis forwarded to the underlying `<Button>`. */
|
|
15
|
+
emphasis?: ButtonProps["emphasis"]; /** Size forwarded to the underlying `<Button>`. */
|
|
16
|
+
size?: ButtonProps["size"]; /** Button label content. Falls back to "Submit". */
|
|
17
|
+
children?: ReactNode;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* FormSubmit — a submit `<Button>` wired to the form's submit-readiness. While
|
|
21
|
+
* the `onSubmit` promise is in flight the label is blurred with a corner spinner
|
|
22
|
+
* (`Loading variant="busy"`) and the button is disabled + `aria-busy`.
|
|
23
|
+
*/
|
|
24
|
+
declare function FormSubmit({
|
|
25
|
+
form,
|
|
26
|
+
disableWhenInvalid,
|
|
27
|
+
emphasis,
|
|
28
|
+
size,
|
|
29
|
+
children
|
|
30
|
+
}: FormSubmitProps): JSX.Element;
|
|
31
|
+
declare namespace FormSubmit {
|
|
32
|
+
var displayName: string;
|
|
33
|
+
}
|
|
34
|
+
//#endregion
|
|
35
|
+
export { FormSubmit, FormSubmitProps };
|
|
36
|
+
//# sourceMappingURL=FormSubmit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSubmit.d.ts","names":[],"sources":["../../src/FormSubmit.tsx"],"mappings":";;;;;KAMY,eAAA;+DAEV,IAAA,EAAM,UAAA;EAFmB;;;;;;EASzB,kBAAA,YAMoB;EAJpB,QAAA,GAAW,WAAA,cATL;EAWN,IAAA,GAAO,WAAA,UAFP;EAIA,QAAA,GAAW,SAAA;AAAA;;;;;AAAS;iBAQN,UAAA;EACd,IAAA;EACA,kBAAA;EACA,QAAA;EACA,IAAA;EACA;AAAA,GACC,eAAA,GAAkB,GAAA,CAAI,OAAA;AAAA,kBANT,UAAA;EAAA,IAAU,WAAA;AAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { useStore } from "@tanstack/react-form";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import Button from "@pindoba/react-button";
|
|
4
|
+
import Loading from "@pindoba/react-loading";
|
|
5
|
+
//#region src/FormSubmit.tsx
|
|
6
|
+
/**
|
|
7
|
+
* FormSubmit — a submit `<Button>` wired to the form's submit-readiness. While
|
|
8
|
+
* the `onSubmit` promise is in flight the label is blurred with a corner spinner
|
|
9
|
+
* (`Loading variant="busy"`) and the button is disabled + `aria-busy`.
|
|
10
|
+
*/
|
|
11
|
+
function FormSubmit({ form, disableWhenInvalid = false, emphasis = "primary", size, children }) {
|
|
12
|
+
const { canSubmit, isSubmitting } = useStore(form.store, (state) => ({
|
|
13
|
+
canSubmit: state.canSubmit,
|
|
14
|
+
isSubmitting: state.isSubmitting
|
|
15
|
+
}));
|
|
16
|
+
return /* @__PURE__ */ jsx(Loading, {
|
|
17
|
+
loading: isSubmitting,
|
|
18
|
+
variant: "busy",
|
|
19
|
+
indicator: true,
|
|
20
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
21
|
+
type: "submit",
|
|
22
|
+
emphasis,
|
|
23
|
+
size,
|
|
24
|
+
disabled: isSubmitting || disableWhenInvalid && !canSubmit,
|
|
25
|
+
"aria-busy": isSubmitting ? "true" : void 0,
|
|
26
|
+
children: children ?? "Submit"
|
|
27
|
+
})
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
FormSubmit.displayName = "FormSubmit";
|
|
31
|
+
//#endregion
|
|
32
|
+
export { FormSubmit };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=FormSubmit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSubmit.js","names":[],"sources":["../../src/FormSubmit.tsx"],"sourcesContent":["import Button, { type ButtonProps } from \"@pindoba/react-button\";\nimport Loading from \"@pindoba/react-loading\";\nimport { useStore } from \"@tanstack/react-form\";\nimport type { JSX, ReactNode } from \"react\";\nimport type { AnyFormApi } from \"./types\";\n\nexport type FormSubmitProps = {\n /** The TanStack form instance returned by `useForm(...)`. */\n form: AnyFormApi;\n /**\n * Also disable while the form is invalid (not just while submitting). Off by\n * default — the button stays clickable so submitting an invalid form surfaces\n * its errors instead of leaving the user stuck on a disabled control.\n * @default false\n */\n disableWhenInvalid?: boolean;\n /** Emphasis forwarded to the underlying `<Button>`. */\n emphasis?: ButtonProps[\"emphasis\"];\n /** Size forwarded to the underlying `<Button>`. */\n size?: ButtonProps[\"size\"];\n /** Button label content. Falls back to \"Submit\". */\n children?: ReactNode;\n};\n\n/**\n * FormSubmit — a submit `<Button>` wired to the form's submit-readiness. While\n * the `onSubmit` promise is in flight the label is blurred with a corner spinner\n * (`Loading variant=\"busy\"`) and the button is disabled + `aria-busy`.\n */\nexport function FormSubmit({\n form,\n disableWhenInvalid = false,\n emphasis = \"primary\",\n size,\n children,\n}: FormSubmitProps): JSX.Element {\n const { canSubmit, isSubmitting } = useStore(form.store, (state) => ({\n canSubmit: state.canSubmit,\n isSubmitting: state.isSubmitting,\n }));\n\n return (\n <Loading loading={isSubmitting} variant=\"busy\" indicator>\n <Button\n type=\"submit\"\n emphasis={emphasis}\n size={size}\n disabled={isSubmitting || (disableWhenInvalid && !canSubmit)}\n aria-busy={isSubmitting ? \"true\" : undefined}\n >\n {children ?? \"Submit\"}\n </Button>\n </Loading>\n );\n}\n\nFormSubmit.displayName = \"FormSubmit\";\n"],"mappings":";;;;;;;;;;AA6BA,SAAgB,WAAW,EACzB,MACA,qBAAqB,OACrB,WAAW,WACX,MACA,YAC+B;CAC/B,MAAM,EAAE,WAAW,iBAAiB,SAAS,KAAK,QAAQ,WAAW;EACnE,WAAW,MAAM;EACjB,cAAc,MAAM;CACtB,EAAE;CAEF,OACE,oBAAC,SAAD;EAAS,SAAS;EAAc,SAAQ;EAAO,WAAA;YAC7C,oBAAC,QAAD;GACE,MAAK;GACK;GACJ;GACN,UAAU,gBAAiB,sBAAsB,CAAC;GAClD,aAAW,eAAe,SAAS,KAAA;aAElC,YAAY;EACP,CAAA;CACD,CAAA;AAEb;AAEA,WAAW,cAAc"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { AnyFieldApi, AnyFormApi } from "@tanstack/react-form";
|
|
2
|
+
import { FormFieldErrorMode, FormFieldErrorMode as FormFieldErrorMode$1 } from "@pindoba/core-tanstack-form";
|
|
3
|
+
import { FieldFeedback, FieldOrientation, FieldPassThrough, FieldSize } from "@pindoba/core-field";
|
|
4
|
+
import { ReactNode } from "react";
|
|
5
|
+
|
|
6
|
+
//#region src/types.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Field-level presentation props shared by `<FormField>` and every convenience
|
|
9
|
+
* wrapper (`<FormInput>`, `<FormSelect>`, `<FormCheckbox>`). These mirror the
|
|
10
|
+
* presentational `<Field>` props; the adapter supplies `error` from TanStack.
|
|
11
|
+
*/
|
|
12
|
+
interface FormFieldOwnProps {
|
|
13
|
+
/** Label text shown above (or beside) the control. */
|
|
14
|
+
label?: string;
|
|
15
|
+
/** Help text rendered under the control. */
|
|
16
|
+
description?: string;
|
|
17
|
+
/** Renders a required `*` after the label. */
|
|
18
|
+
required?: boolean;
|
|
19
|
+
/** Optional-hint text after the label when not required. */
|
|
20
|
+
optionalText?: string;
|
|
21
|
+
/** Disables the field and forwards `disabled` to the control. */
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
/** Size variant, kept in sync with the control. */
|
|
24
|
+
size?: FieldSize;
|
|
25
|
+
/** Label/control layout direction. */
|
|
26
|
+
orientation?: FieldOrientation;
|
|
27
|
+
/** Explicit feedback override; defaults to error-derived danger / neutral. */
|
|
28
|
+
feedback?: FieldFeedback;
|
|
29
|
+
/** Tooltip attached to an info trigger next to the label. */
|
|
30
|
+
labelTooltip?: ReactNode;
|
|
31
|
+
/** When the field's errors become visible. @default "touched" */
|
|
32
|
+
errorMode?: FormFieldErrorMode$1;
|
|
33
|
+
/** Per-slot escape hatch for styling and attributes. */
|
|
34
|
+
passThrough?: FieldPassThrough;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { type AnyFieldApi, type AnyFormApi, type FormFieldErrorMode, FormFieldOwnProps };
|
|
38
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/types.ts"],"mappings":";;;;;;;AAmBA;;;;UAAiB,iBAAA;EAgBJ;EAdX,KAAA;EAkBY;EAhBZ,WAAA;EAkB8B;EAhB9B,QAAA;EAJA;EAMA,YAAA;EAFA;EAIA,QAAA;EAAA;EAEA,IAAA,GAAO,SAAA;EAAA;EAEP,WAAA,GAAc,gBAAA;EAAA;EAEd,QAAA,GAAW,aAAA;EAAA;EAEX,YAAA,GAAe,SAAA;EAAA;EAEf,SAAA,GAAY,oBAAA;EAAA;EAEZ,WAAA,GAAc,gBAAA;AAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pindoba/react-tanstack-form",
|
|
3
|
+
"version": "0.0.0-alpha-20260617191010",
|
|
4
|
+
"homepage": "https://github.com/EduardoLopes/pindoba/tree/main/packages/blocks/react/tanstack-form#README.md",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/EduardoLopes/pindoba.git",
|
|
8
|
+
"directory": "packages/blocks/react/tanstack-form"
|
|
9
|
+
},
|
|
10
|
+
"sideEffects": false,
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./demos": "./src/demos/index.ts",
|
|
24
|
+
"./demos/basic": "./src/demos/basic.tsx",
|
|
25
|
+
"./demos/mixed-controls": "./src/demos/mixed-controls.tsx",
|
|
26
|
+
"./demos/generic-field": "./src/demos/generic-field.tsx"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/react": "^19.2.17",
|
|
30
|
+
"@types/react-dom": "^19.2.3",
|
|
31
|
+
"react": "^19.2.7",
|
|
32
|
+
"react-dom": "^19.2.7",
|
|
33
|
+
"tsdown": "^0.22.2",
|
|
34
|
+
"typescript": "^6.0.3",
|
|
35
|
+
"zod": "^4.4.3",
|
|
36
|
+
"@repo/typescript-config": "0.0.0-alpha-20260320034942"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": "^18.3.1 || ^19.0.0"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@tanstack/react-form": "^1.33.0",
|
|
43
|
+
"@pindoba/core-field": "0.0.0-alpha-20260617191010",
|
|
44
|
+
"@pindoba/core-tanstack-form": "0.0.0-alpha-20260617191010",
|
|
45
|
+
"@pindoba/react-affix": "0.0.0-alpha-20260617191010",
|
|
46
|
+
"@pindoba/react-checkbox": "0.0.0-alpha-20260617191010",
|
|
47
|
+
"@pindoba/react-field": "0.0.0-alpha-20260617191010",
|
|
48
|
+
"@pindoba/react-button": "0.0.0-alpha-20260617191010",
|
|
49
|
+
"@pindoba/react-input": "0.0.0-alpha-20260617191010",
|
|
50
|
+
"@pindoba/react-loading": "0.0.0-alpha-20260617191010",
|
|
51
|
+
"@pindoba/react-select": "0.0.0-alpha-20260617191010",
|
|
52
|
+
"@pindoba/styled-system": "0.0.0-alpha-20260617191010",
|
|
53
|
+
"@pindoba/core-listbox": "0.0.0-alpha-20260617191010"
|
|
54
|
+
},
|
|
55
|
+
"publishConfig": {
|
|
56
|
+
"access": "public"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "tsdown",
|
|
60
|
+
"dev": "tsdown --watch",
|
|
61
|
+
"check": "tsc --noEmit",
|
|
62
|
+
"lint": "TIMING=1 eslint . --max-warnings 0",
|
|
63
|
+
"lint:fix": "TIMING=1 eslint . --fix --max-warnings 0",
|
|
64
|
+
"link": "pnpm link",
|
|
65
|
+
"unlink": "pnpm unlink",
|
|
66
|
+
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist",
|
|
67
|
+
"format": "prettier --check . --ignore-path \"$PRETTIER_IGNORE_PATH\"",
|
|
68
|
+
"format:fix": "prettier --write . --ignore-path \"$PRETTIER_IGNORE_PATH\""
|
|
69
|
+
}
|
|
70
|
+
}
|