haze-ui 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,9 @@
4
4
 
5
5
  English | [简体中文](./README-zh_CN.md)
6
6
 
7
+ [![npm](https://img.shields.io/npm/v/haze-ui)](https://www.npmjs.com/package/haze-ui)
8
+ [![CI](https://github.com/wmzy/haze-ui/actions/workflows/ci.yml/badge.svg)](https://github.com/wmzy/haze-ui/actions/workflows/ci.yml)
9
+
7
10
  ## Features
8
11
 
9
12
  - Integrated [react use control](https://github.com/wmzy/react-use-control) provides component internal states
@@ -86,6 +89,40 @@ function ProfileForm() {
86
89
  surfaces the first error in a `role="alert"` element — no manual
87
90
  `FieldError` wiring.
88
91
 
92
+ #### `mode`: per-field validation timing (react-f0rm ≥ 0.6)
93
+
94
+ Pass `mode` to validate one field on its own schedule instead of the
95
+ form-wide validation mode — other fields are unaffected. It accepts
96
+ react-f0rm's `ValidationMode` values: `'onSubmit'` (default form
97
+ behavior), `'onBlur'`, `'onChange'`, `'onTouched'` or `'all'`. Omit it to
98
+ keep the form's mode.
99
+
100
+ ```jsx
101
+ <FormItem
102
+ form={form}
103
+ name="email"
104
+ label="Email"
105
+ mode="onBlur"
106
+ validate={(v) => (v.includes('@') ? undefined : 'must be an email')}
107
+ >
108
+ {({ id, errorId, invalid, onBlur, control }) => (
109
+ <Input
110
+ id={id}
111
+ value={control}
112
+ aria-invalid={invalid}
113
+ aria-describedby={errorId}
114
+ onBlur={onBlur}
115
+ />
116
+ )}
117
+ </FormItem>
118
+ ```
119
+
120
+ With `mode="onBlur"` (and the binding's `onBlur` passed to the control,
121
+ as above) the email field is validated the moment it loses focus — no
122
+ submit needed. `mode` accepts `'onSubmit'`, `'onBlur'`, `'onChange'`,
123
+ `'onTouched'` or `'all'`; only this field's schedule changes, the rest
124
+ of the form keeps its own `mode`.
125
+
89
126
  ## Related Projects
90
127
 
91
128
  - [react-use-control](https://github.com/wmzy/react-use-control)
@@ -6,34 +6,34 @@ import { useId as i } from "react";
6
6
  import { useField as a, useFieldErrors as o } from "react-f0rm";
7
7
  //#region src/lib/form/FormItem.tsx
8
8
  var s = "haze-FormItem__item", c = "haze-FormItem__labelText", l = "haze-FormItem__errorText";
9
- function u({ form: u, name: d, label: f, validate: p, className: m, children: h }) {
10
- let g = `haze-field-${i()}`, _ = `${g}-error`;
11
- a({
9
+ function u({ form: u, name: d, label: f, validate: p, mode: m, className: h, children: g }) {
10
+ let _ = `haze-field-${i()}`, v = `${_}-error`, { onBlur: y } = a({
12
11
  form: u,
13
12
  name: d,
14
- validate: p
15
- });
16
- let v = o(u, d), y = t(u, d), b = v.length > 0;
13
+ validate: p,
14
+ mode: m
15
+ }), b = o(u, d), x = t(u, d), S = b.length > 0;
17
16
  return /* @__PURE__ */ r("div", {
18
- className: e([s, m]),
17
+ className: e([s, h]),
19
18
  children: [
20
19
  f !== void 0 && /* @__PURE__ */ n("label", {
21
- htmlFor: g,
20
+ htmlFor: _,
22
21
  className: e(c),
23
22
  children: f
24
23
  }),
25
- h({
26
- id: g,
27
- errorId: _,
28
- invalid: b,
29
- errors: v,
30
- control: y
31
- }),
32
- b && /* @__PURE__ */ n("span", {
24
+ g({
33
25
  id: _,
26
+ errorId: v,
27
+ invalid: S,
28
+ errors: b,
29
+ onBlur: y,
30
+ control: x
31
+ }),
32
+ S && /* @__PURE__ */ n("span", {
33
+ id: v,
34
34
  role: "alert",
35
35
  className: e(l),
36
- children: v[0].message
36
+ children: b[0].message
37
37
  })
38
38
  ]
39
39
  });
@@ -1,5 +1,5 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { FieldError, FieldPath, Name } from 'react-f0rm';
2
+ import type { FieldError, FieldPath, Name, ValidationMode } from 'react-f0rm';
3
3
  import type { Control } from 'react-use-control';
4
4
  import type { FormInstance, PathValueOf } from './useFormControl';
5
5
  /**
@@ -22,6 +22,10 @@ export type FormItemBinding<TValues, P extends FieldPath<TValues> | Name> = {
22
22
  invalid: boolean;
23
23
  /** every error registered for the field, in insertion order */
24
24
  errors: FieldError[];
25
+ /** react-f0rm blur hook for this field — pass to the control's `onBlur`
26
+ * (`<Input onBlur={onBlur}/>`) so blur-scheduled validation modes
27
+ * (`mode='onBlur' | 'onTouched' | 'all'`) fire when the field loses focus. */
28
+ onBlur: () => void;
25
29
  /** Control bound to the field value — pass to a control prop */
26
30
  control: Control<PathValueOf<TValues, P>>;
27
31
  };
@@ -32,6 +36,11 @@ export type FormItemProps<TValues extends Record<string, any> = any, P extends F
32
36
  /** Field-level validator, registered through react-f0rm's own
33
37
  * `useField` channel — validated per the form's `mode` and on submit. */
34
38
  validate?: FieldValidator;
39
+ /** Per-field validation mode override (react-f0rm ≥0.6): when given,
40
+ * this field validates on its own schedule — e.g. `'onBlur'` — instead
41
+ * of the form's `mode`; other fields are unaffected. Omit to keep the
42
+ * form-wide behavior. */
43
+ mode?: ValidationMode;
35
44
  className?: string;
36
45
  children: (binding: FormItemBinding<TValues, P>) => ReactNode;
37
46
  };
@@ -52,4 +61,4 @@ export type FormItemProps<TValues extends Record<string, any> = any, P extends F
52
61
  * `<span id={errorId} role='alert'>` next to the children; with no errors
53
62
  * no extra element is rendered.
54
63
  */
55
- export default function FormItem<TValues extends Record<string, any> = any, P extends FieldPath<TValues> | Name = Name>({ form, name, label, validate, className, children }: FormItemProps<TValues, P>): import("react").JSX.Element;
64
+ export default function FormItem<TValues extends Record<string, any> = any, P extends FieldPath<TValues> | Name = Name>({ form, name, label, validate, mode, className, children }: FormItemProps<TValues, P>): import("react").JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haze-ui",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "type": "module",
5
5
  "description": "A React UI component library powered by react-use-control and Linaria",
6
6
  "main": "./dist/index.js",
@@ -98,7 +98,7 @@
98
98
  "ramda": "^0.32.0",
99
99
  "react": "^19.2.8",
100
100
  "react-dom": "^19.2.8",
101
- "react-f0rm": "^0.5.0",
101
+ "react-f0rm": "^0.6.0",
102
102
  "react-icons": "^5.7.0",
103
103
  "rollup-plugin-type-as-json-schema": "^0.2.6",
104
104
  "semantic-release": "^25.0.9",