@llmnative/react 1.48.0 → 2.0.1

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.
@@ -33,6 +33,7 @@ export interface I18nDict {
33
33
  requiredField: string;
34
34
  requiredFieldGeneric: string;
35
35
  saveSuccess: string;
36
+ saveError: string;
36
37
  deleteSuccess: string;
37
38
  noticeRequiredFields: string;
38
39
  noChangesToSave?: string;
@@ -66,7 +66,7 @@ export type { SortableListProps, SortableListCard, SortableListReorderMeta } fro
66
66
  export { default as SideNav } from './blocks/SideNav';
67
67
  export type { SideNavProps, SideNavItemDef } from './blocks/SideNav';
68
68
  export { default as Form, useFormContext } from './widgets/Form';
69
- export type { FieldLabel, FormFieldProps, FormProps, FormDeleteArgs, FormDeleteHandler, FormFinallyArgs, FormFinallyHandler, FormSaveArgs, FormSaveHandler, ChangeHandler, FieldOnChange } from './widgets/Form';
69
+ export type { FieldLabel, FormFieldProps, FormProps, FormDeleteArgs, FormDeleteHandler, FormFinallyArgs, FormFinallyHandler, FormSaveArgs, FormSaveHandler, FormSaveProps, FormSubmitArgs, FormSubmitHandler, FormSubmitProps, ChangeHandler, FieldOnChange } from './widgets/Form';
70
70
  export { FormControllerContext, useFormActions, useFormController } from './widgets/form-controller';
71
71
  export type { FormActionEvent, FormController, FormControllerActions, FormControllerState, FormDraftStatus } from './widgets/form-controller';
72
72
  export { default as Grid } from './widgets/Grid';
@@ -17,6 +17,14 @@ interface BaseInputProps extends FormFieldProps {
17
17
  validator?: (value: FieldValue) => string | undefined | Promise<string | undefined>;
18
18
  /** Content rendered as an absolute overlay inside the input (right side). No addon border/bg. */
19
19
  afterInset?: React.ReactNode;
20
+ /** The keyboard a phone shows (e.g. `"numeric"` for a code of digits). */
21
+ inputMode?: React.HTMLAttributes<HTMLInputElement>['inputMode'];
22
+ /** At most this many characters can be typed. */
23
+ maxLength?: number;
24
+ /** A regular expression the value must match, for the browser (e.g. `"[0-9]{6}"`); `validator` for the Form's own check. */
25
+ pattern?: string;
26
+ /** What the browser may fill in (e.g. `"one-time-code"` for a code received by email or SMS, `"tel"`, `"email"`). */
27
+ autoComplete?: string;
20
28
  }
21
29
  interface LabelProps {
22
30
  /** A text or a React node, drawn inside the `<label>` before the required mark. */
@@ -73,10 +81,12 @@ export declare const fieldAddonClass = "inline-flex shrink-0 items-center border
73
81
  export declare const FieldError: ({ message }: {
74
82
  message: string;
75
83
  }) => React.JSX.Element;
76
- export declare const Input: ({ name, onChange, defaultValue, placeholder, label, type, required, readOnlyAfterSet, disabled, before, after, afterInset, feedback, min, max, step, id, labelClassName, inheritWrapperClassName, wrapperClassName, className, validator, labelMode, }: BaseInputProps) => React.JSX.Element;
84
+ export declare const Input: ({ name, onChange, defaultValue, placeholder, label, type, required, readOnlyAfterSet, disabled, before, after, afterInset, feedback, min, max, step, id, labelClassName, inheritWrapperClassName, wrapperClassName, className, validator, labelMode, inputMode, maxLength, pattern, autoComplete, }: BaseInputProps) => React.JSX.Element;
77
85
  export declare const String: (props: InputProps) => React.JSX.Element;
78
86
  export declare const Number: (props: InputProps) => React.JSX.Element;
79
87
  export declare const Email: (props: InputProps) => React.JSX.Element;
88
+ /** A phone number: the phone shows its number keyboard. */
89
+ export declare const Tel: (props: InputProps) => React.JSX.Element;
80
90
  export declare const Password: (props: InputProps) => React.JSX.Element;
81
91
  export declare const Color: ({ className, ...props }: InputProps) => React.JSX.Element;
82
92
  export declare const Date: (props: InputProps) => React.JSX.Element;
@@ -17,7 +17,7 @@ export type FieldOnChange = (params: {
17
17
  record: RecordProps;
18
18
  onChange: FormHandleChange;
19
19
  }) => void;
20
- export type InputType = "text" | "number" | "email" | "password" | "color" | "date" | "time" | "datetime-local" | "week" | "month" | "range" | "checkbox" | "radio" | "url";
20
+ export type InputType = "text" | "number" | "email" | "tel" | "password" | "color" | "date" | "time" | "datetime-local" | "week" | "month" | "range" | "checkbox" | "radio" | "url";
21
21
  export type LabelMode = "default" | "floating";
22
22
  interface FormContextProps {
23
23
  name: string;
@@ -96,13 +96,28 @@ export type FormDeleteArgs = {
96
96
  };
97
97
  export type FormFinallyArgs = {
98
98
  record?: RecordProps;
99
- action: 'create' | 'update' | 'delete';
99
+ /** `submit` after `onSubmit` (action form); the others after a save or a delete. */
100
+ action: 'create' | 'update' | 'delete' | 'submit';
100
101
  };
101
- export type FormSaveHandler = (args: FormSaveArgs) => Promise<string | undefined>;
102
+ /** What `onSubmit` receives: the record of the fields, as typed. */
103
+ export type FormSubmitArgs = {
104
+ record: RecordProps;
105
+ };
106
+ /**
107
+ * Called on save. Return a provider path to write the record there, `undefined` to write it at the
108
+ * Form's `path` (nothing written without a `path`), `false` when it failed and the page already says
109
+ * why (nothing written, no notice, `save()` resolves `false`). Throwing shows its message in the Form's notice.
110
+ */
111
+ export type FormSaveHandler = (args: FormSaveArgs) => Promise<string | undefined | false>;
102
112
  export type FormDeleteHandler = (args: FormDeleteArgs) => Promise<string | undefined>;
103
113
  export type FormFinallyHandler = (args: FormFinallyArgs) => Promise<boolean>;
104
- /** Core props shared by all Form variants. */
105
- interface BaseFormProps {
114
+ /**
115
+ * The action of an action form. Throwing shows its message in the Form's notice; returning `false` means it
116
+ * failed and the page already says why (no notice, no `onComplete`, `save()` resolves `false`).
117
+ */
118
+ export type FormSubmitHandler = (args: FormSubmitArgs) => Promise<void | false> | void | false;
119
+ /** Props shared by both kinds of Form: the one that saves a record and the one that runs an action. */
120
+ interface FormCommonProps {
106
121
  /** Visual wrapper: `"card"` adds a card shell; `"empty"` renders bare. */
107
122
  appearance?: "card" | "empty";
108
123
  /** Shared controller for external actions, custom save buttons and draft state. */
@@ -111,32 +126,16 @@ interface BaseFormProps {
111
126
  header?: React.ReactNode;
112
127
  /** Custom content rendered in the form footer area. */
113
128
  footer?: React.ReactNode;
114
- /** Provider path for data load and save. Omit for a pure local form. */
115
- path?: string;
116
- /** Generate a custom primary key for new records instead of auto-push. */
117
- keyGenerator?: (record: RecordProps) => string;
118
129
  /** Transform the record after loading from the provider. */
119
130
  onLoad?: (record: RecordProps) => void;
120
131
  /** Called on every field change with the current record state. */
121
132
  onRecordChange?: (record: RecordProps) => void;
122
- /** Transform the record before saving. Return the final record or a custom path. */
123
- onSave?: FormSaveHandler;
124
- /** Called before deletion. Return a path override or `undefined`. */
125
- onDelete?: FormDeleteHandler;
126
- /** Called after save or delete. Return `false` to suppress default navigation. */
133
+ /** Called after a save, a delete or a submit that worked. Return `false` to suppress default navigation. */
127
134
  onComplete?: FormFinallyHandler;
128
135
  /** Log field-change events to the console (dev helper). */
129
136
  log?: boolean;
130
- /** Show the inline save/delete notice banner. Defaults to `true`. */
137
+ /** Show the inline notice banner (saved, deleted, required fields, errors). Defaults to `true`; `false` lets an error of `onSave`/`onSubmit` reject `save()` instead. */
131
138
  showNotice?: boolean;
132
- /**
133
- * Whether saving needs a changed field. Defaults to `true`: an unchanged form says "No changes
134
- * to save" and its save is disabled. `false` makes it an action form (CR-117), whose initial
135
- * values are already a valid submission (e.g. start a release with the proposed version):
136
- * `save()` validates and calls `onSave` even when nothing changed. `isDirty` still tells
137
- * whether something did.
138
- */
139
- requireChanges?: boolean;
140
139
  /**
141
140
  * Stable bucket that isolates this form's local draft. Omit to disable draft persistence.
142
141
  * The Form appends its own path/route identity, so one bucket safely serves many forms.
@@ -163,32 +162,61 @@ interface BaseFormProps {
163
162
  * `[&>form]:` child selector on `wrapperClassName`.
164
163
  */
165
164
  formClassName?: string;
166
- }
167
- interface FormDefaultProps extends BaseFormProps {
168
- children: React.ReactNode | ((fields: FormTree) => React.ReactNode) | ((args: {
165
+ /** Field elements, a render-prop receiving the field tree, or a record-aware function. */
166
+ children?: React.ReactNode | ((fields: FormTree) => React.ReactNode) | ((args: {
169
167
  record?: RecordProps;
170
168
  }) => React.ReactNode);
169
+ /** Initial field values (a new record, or the proposed values of an action). */
171
170
  defaultValues?: RecordProps;
172
171
  }
173
- interface FormDatabaseProps extends FormDefaultProps {
174
- path: string;
172
+ /** What a Form that saves a record takes: where, how and what it writes. */
173
+ interface FormSaveOptions {
174
+ /** Provider path the record is read from and written to. Omitted: read from the route hash if any, else nothing read; nothing written unless `onSave` returns a path. */
175
+ path?: string;
176
+ /** Generate a custom primary key for new records instead of auto-push. */
177
+ keyGenerator?: (record: RecordProps) => string;
178
+ /**
179
+ * Called on save, after the fields are valid and only when one changed. Return a provider path to
180
+ * write the record there, `undefined` to write it at `path`. To run an action instead (call a
181
+ * command, send a code) use `onSubmit`.
182
+ */
183
+ onSave?: FormSaveHandler;
184
+ /** Called before deletion. Return a path override or `undefined`. */
185
+ onDelete?: FormDeleteHandler;
175
186
  }
176
- interface FormModelProps extends BaseFormProps {
177
- model: ModelProps;
178
- children?: ((fields: FormTree) => React.ReactNode);
187
+ /**
188
+ * A Form that saves a record: it reads it from `path`, writes it there (or where `onSave` says),
189
+ * shows "Saved", and saves only when a field changed. It shows its own Save button in the card.
190
+ */
191
+ export interface FormSaveProps extends FormCommonProps, FormSaveOptions {
192
+ onSubmit?: never;
179
193
  }
180
194
  /**
181
- * Public props for `<Form>`.
182
- * When `path` points to an existing record the form loads its data automatically.
183
- * When `keyGenerator` or `defaultValues` is set the form operates in create-only mode.
195
+ * An action form: it saves nothing. On submit (Enter in a field, or `useFormController().save()` from
196
+ * your own button) it checks the fields and calls `onSubmit({ record })`, changed or not. No Save
197
+ * button, no "Saved": the button and what follows are yours; an error of `onSubmit` shows in its
198
+ * notice. It takes no `path`, `onSave`, `onDelete` or `keyGenerator`.
184
199
  */
185
- export interface FormProps extends BaseFormProps {
186
- /** Field elements, a render-prop receiving the field tree, or a record-aware function. */
187
- children?: React.ReactNode | ((fields: FormTree) => React.ReactNode) | ((args: {
188
- record?: RecordProps;
189
- }) => React.ReactNode);
190
- /** Initial field values for a new record. */
191
- defaultValues?: RecordProps;
200
+ export interface FormSubmitProps extends FormCommonProps {
201
+ /** The action: e.g. `({ record }) => call('requestLoginCode', record)`. */
202
+ onSubmit: FormSubmitHandler;
203
+ path?: never;
204
+ keyGenerator?: never;
205
+ onSave?: never;
206
+ onDelete?: never;
207
+ }
208
+ /** Public props for `<Form>`: a Form that saves a record (`FormSaveProps`) or an action form (`FormSubmitProps`, with `onSubmit`). */
209
+ export type FormProps = FormSaveProps | FormSubmitProps;
210
+ /** What the inner Form takes: either kind, checked by `Form`. */
211
+ interface FormDataProps extends FormCommonProps, FormSaveOptions {
212
+ onSubmit?: FormSubmitHandler;
213
+ }
214
+ interface FormDatabaseProps extends FormDataProps {
215
+ path: string;
216
+ }
217
+ interface FormModelProps extends Omit<FormCommonProps, 'children'>, FormSaveOptions {
218
+ model: ModelProps;
219
+ children?: ((fields: FormTree) => React.ReactNode);
192
220
  }
193
221
  declare function Form(props: FormProps): React.JSX.Element;
194
222
  export declare const FormDatabase: (props: FormDatabaseProps) => React.JSX.Element;