@zeno-lib/forms 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/package.json +21 -11
  2. package/src/addons/validation-spinner.tsx +3 -4
  3. package/src/create-form.tsx +49 -0
  4. package/src/create-zeno-form.tsx +531 -0
  5. package/src/fields/checkbox-field.tsx +15 -12
  6. package/src/fields/combobox-field.tsx +13 -14
  7. package/src/fields/date-picker-field.tsx +18 -15
  8. package/src/fields/input-field.tsx +12 -13
  9. package/src/fields/number-field.tsx +1 -2
  10. package/src/fields/otp-field.tsx +15 -12
  11. package/src/fields/radio-group-field.tsx +12 -13
  12. package/src/fields/reset-button.tsx +2 -3
  13. package/src/fields/select-field.tsx +12 -13
  14. package/src/fields/slider-field.tsx +11 -12
  15. package/src/fields/submit-button.tsx +3 -4
  16. package/src/fields/switch-field.tsx +15 -12
  17. package/src/fields/textarea-field.tsx +12 -13
  18. package/src/form-element.tsx +51 -0
  19. package/src/index.ts +14 -0
  20. package/src/lib/apply-validation-error.test.ts +1 -2
  21. package/src/lib/required-indicator.tsx +1 -1
  22. package/src/lib/schema-defaults.test.ts +1 -2
  23. package/src/lib/schema-required.test.ts +98 -6
  24. package/src/lib/schema-required.ts +126 -22
  25. package/src/lib/use-is-invalid.ts +4 -4
  26. package/src/lib/use-rebased-default-values.ts +42 -0
  27. package/src/lib/use-unsaved-changes-warning.ts +3 -3
  28. package/src/lib/validation-error.test.ts +1 -1
  29. package/src/lib/validation-logic.test.ts +1 -1
  30. package/src/lib/validation-modes.test-d.ts +1 -1
  31. package/src/lib/validation-modes.test.ts +12 -2
  32. package/src/lib/validation-modes.ts +3 -1
  33. package/src/use-app-fields.test-d.ts +8 -25
  34. package/src/use-app-fields.test.tsx +8 -32
  35. package/src/use-form.cascade.test.tsx +4 -6
  36. package/src/use-form.focus-invalid.test.tsx +198 -0
  37. package/src/use-form.reset-defaults.test.tsx +125 -0
  38. package/src/use-form.test-d.ts +2 -3
  39. package/src/use-form.test.tsx +12 -14
  40. package/src/use-form.unsaved-warning.test.tsx +4 -13
  41. package/src/use-form.validation-modes.test.tsx +10 -8
  42. package/src/form.tsx +0 -105
  43. package/src/use-app-fields.tsx +0 -272
  44. package/src/use-form.tsx +0 -450
@@ -1,5 +1,13 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import type { ReactNode } from "react"
3
11
  import {
4
12
  Combobox,
5
13
  ComboboxContent,
@@ -7,25 +15,16 @@ import {
7
15
  ComboboxInput,
8
16
  ComboboxItem,
9
17
  ComboboxList,
10
- } from "@zeno-lib/ui/combobox"
18
+ } from "@/components/ui/combobox"
11
19
  import {
12
20
  Field,
13
21
  FieldDescription,
14
22
  FieldError,
15
23
  FieldLabel,
16
- } from "@zeno-lib/ui/field"
17
- import { InputGroupAddon } from "@zeno-lib/ui/input-group"
18
- import { Spinner } from "@zeno-lib/ui/spinner"
19
- import type { ReactNode } from "react"
20
-
21
- import { describedBy } from "../lib/aria"
22
- import { useFieldContext } from "../lib/contexts"
24
+ } from "@/components/ui/field"
25
+ import { InputGroupAddon } from "@/components/ui/input-group"
26
+ import { Spinner } from "@/components/ui/spinner"
23
27
  import { RequiredIndicator } from "../lib/required-indicator"
24
- import {
25
- useHideFieldErrors,
26
- useIsFieldRequired,
27
- useIsInvalid,
28
- } from "../lib/use-is-invalid"
29
28
 
30
29
  type ComboboxItemObject<V> = { value: V; label: string }
31
30
 
@@ -112,7 +111,7 @@ function ComboboxField<T = string>({
112
111
  : ((fieldValue ?? null) as T | null)
113
112
 
114
113
  return (
115
- <Field data-invalid={isInvalid}>
114
+ <Field data-field={field.name} data-invalid={isInvalid}>
116
115
  {label && (
117
116
  <FieldLabel htmlFor={field.name}>
118
117
  {label}
@@ -1,25 +1,28 @@
1
1
  "use client"
2
2
 
3
- import { buttonVariants } from "@zeno-lib/ui/button"
4
- import { Calendar } from "@zeno-lib/ui/calendar"
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import type { ComponentProps, ReactNode } from "react"
11
+ import { buttonVariants } from "@/components/ui/button"
12
+ import { Calendar } from "@/components/ui/calendar"
5
13
  import {
6
14
  Field,
7
15
  FieldDescription,
8
16
  FieldError,
9
17
  FieldLabel,
10
- } from "@zeno-lib/ui/field"
11
- import { cn } from "@zeno-lib/ui/lib/utils"
12
- import { Popover, PopoverContent, PopoverTrigger } from "@zeno-lib/ui/popover"
13
- import type { ComponentProps, ReactNode } from "react"
14
-
15
- import { describedBy } from "../lib/aria"
16
- import { useFieldContext } from "../lib/contexts"
17
- import { RequiredIndicator } from "../lib/required-indicator"
18
+ } from "@/components/ui/field"
18
19
  import {
19
- useHideFieldErrors,
20
- useIsFieldRequired,
21
- useIsInvalid,
22
- } from "../lib/use-is-invalid"
20
+ Popover,
21
+ PopoverContent,
22
+ PopoverTrigger,
23
+ } from "@/components/ui/popover"
24
+ import { cn } from "@/lib/utils"
25
+ import { RequiredIndicator } from "../lib/required-indicator"
23
26
 
24
27
  type CalendarProps = ComponentProps<typeof Calendar>
25
28
 
@@ -69,7 +72,7 @@ function DatePickerField({
69
72
  const empty = !value
70
73
 
71
74
  return (
72
- <Field data-invalid={isInvalid}>
75
+ <Field data-field={field.name} data-invalid={isInvalid}>
73
76
  {label && (
74
77
  <FieldLabel htmlFor={field.name}>
75
78
  {label}
@@ -1,23 +1,22 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import { Children, type ComponentProps, type ReactNode } from "react"
3
11
  import {
4
12
  Field,
5
13
  FieldDescription,
6
14
  FieldError,
7
15
  FieldLabel,
8
- } from "@zeno-lib/ui/field"
9
- import { Input } from "@zeno-lib/ui/input"
10
- import { InputGroup, InputGroupInput } from "@zeno-lib/ui/input-group"
11
- import { Children, type ComponentProps, type ReactNode } from "react"
12
-
13
- import { describedBy } from "../lib/aria"
14
- import { useFieldContext } from "../lib/contexts"
16
+ } from "@/components/ui/field"
17
+ import { Input } from "@/components/ui/input"
18
+ import { InputGroup, InputGroupInput } from "@/components/ui/input-group"
15
19
  import { RequiredIndicator } from "../lib/required-indicator"
16
- import {
17
- useHideFieldErrors,
18
- useIsFieldRequired,
19
- useIsInvalid,
20
- } from "../lib/use-is-invalid"
21
20
 
22
21
  type InputFieldProps = Omit<
23
22
  ComponentProps<typeof Input>,
@@ -66,7 +65,7 @@ function InputField({
66
65
  }
67
66
 
68
67
  return (
69
- <Field data-invalid={isInvalid}>
68
+ <Field data-field={field.name} data-invalid={isInvalid}>
70
69
  {label && (
71
70
  <FieldLabel htmlFor={field.name}>
72
71
  {label}
@@ -1,8 +1,7 @@
1
1
  "use client"
2
2
 
3
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
3
4
  import type { ChangeEvent } from "react"
4
-
5
- import { useFieldContext } from "../lib/contexts"
6
5
  import { InputField, type InputFieldProps } from "./input-field"
7
6
 
8
7
  type NumberFieldProps = Omit<
@@ -1,22 +1,25 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import type { ReactNode } from "react"
3
11
  import {
4
12
  Field,
5
13
  FieldDescription,
6
14
  FieldError,
7
15
  FieldLabel,
8
- } from "@zeno-lib/ui/field"
9
- import { InputOTP, InputOTPGroup, InputOTPSlot } from "@zeno-lib/ui/input-otp"
10
- import type { ReactNode } from "react"
11
-
12
- import { describedBy } from "../lib/aria"
13
- import { useFieldContext } from "../lib/contexts"
14
- import { RequiredIndicator } from "../lib/required-indicator"
16
+ } from "@/components/ui/field"
15
17
  import {
16
- useHideFieldErrors,
17
- useIsFieldRequired,
18
- useIsInvalid,
19
- } from "../lib/use-is-invalid"
18
+ InputOTP,
19
+ InputOTPGroup,
20
+ InputOTPSlot,
21
+ } from "@/components/ui/input-otp"
22
+ import { RequiredIndicator } from "../lib/required-indicator"
20
23
 
21
24
  // Flat surface — `OTPInput`'s prop type is a discriminated union over
22
25
  // `render`/`children`, which doesn't compose cleanly with `Omit`. Listing the
@@ -63,7 +66,7 @@ function OtpField({
63
66
  const isRequired = required ?? schemaRequired
64
67
 
65
68
  return (
66
- <Field data-invalid={isInvalid}>
69
+ <Field data-field={field.name} data-invalid={isInvalid}>
67
70
  {label && (
68
71
  <FieldLabel htmlFor={field.name}>
69
72
  {label}
@@ -1,23 +1,22 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import { type ComponentProps, type ReactNode, useId } from "react"
3
11
  import {
4
12
  Field,
5
13
  FieldDescription,
6
14
  FieldError,
7
15
  FieldLabel,
8
- } from "@zeno-lib/ui/field"
9
- import { cn } from "@zeno-lib/ui/lib/utils"
10
- import { RadioGroup, RadioGroupItem } from "@zeno-lib/ui/radio-group"
11
- import { type ComponentProps, type ReactNode, useId } from "react"
12
-
13
- import { describedBy } from "../lib/aria"
14
- import { useFieldContext } from "../lib/contexts"
16
+ } from "@/components/ui/field"
17
+ import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
18
+ import { cn } from "@/lib/utils"
15
19
  import { RequiredIndicator } from "../lib/required-indicator"
16
- import {
17
- useHideFieldErrors,
18
- useIsFieldRequired,
19
- useIsInvalid,
20
- } from "../lib/use-is-invalid"
21
20
 
22
21
  type RadioGroupFieldProps = Omit<
23
22
  ComponentProps<typeof RadioGroup>,
@@ -46,7 +45,7 @@ function RadioGroupField({
46
45
  const isRequired = required ?? schemaRequired
47
46
 
48
47
  return (
49
- <Field data-invalid={isInvalid}>
48
+ <Field data-field={field.name} data-invalid={isInvalid}>
50
49
  {label && (
51
50
  <FieldLabel>
52
51
  {label}
@@ -1,9 +1,8 @@
1
1
  "use client"
2
2
 
3
- import { Button } from "@zeno-lib/ui/button"
3
+ import { useFormContext } from "@zeno-lib/forms/lib/contexts"
4
4
  import type { ComponentProps, ReactNode } from "react"
5
-
6
- import { useFormContext } from "../lib/contexts"
5
+ import { Button } from "@/components/ui/button"
7
6
 
8
7
  type ResetButtonProps = Omit<ComponentProps<typeof Button>, "onClick" | "type">
9
8
 
@@ -1,28 +1,27 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import type { ComponentProps, ReactNode } from "react"
11
+ import { Children, isValidElement, useMemo } from "react"
3
12
  import {
4
13
  Field,
5
14
  FieldDescription,
6
15
  FieldError,
7
16
  FieldLabel,
8
- } from "@zeno-lib/ui/field"
17
+ } from "@/components/ui/field"
9
18
  import {
10
19
  Select,
11
20
  SelectContent,
12
21
  SelectTrigger,
13
22
  SelectValue,
14
- } from "@zeno-lib/ui/select"
15
- import type { ComponentProps, ReactNode } from "react"
16
- import { Children, isValidElement, useMemo } from "react"
17
-
18
- import { describedBy } from "../lib/aria"
19
- import { useFieldContext } from "../lib/contexts"
23
+ } from "@/components/ui/select"
20
24
  import { RequiredIndicator } from "../lib/required-indicator"
21
- import {
22
- useHideFieldErrors,
23
- useIsFieldRequired,
24
- useIsInvalid,
25
- } from "../lib/use-is-invalid"
26
25
 
27
26
  type SelectFieldProps = Omit<
28
27
  ComponentProps<typeof Select>,
@@ -71,7 +70,7 @@ function SelectField({
71
70
  }, [children])
72
71
 
73
72
  return (
74
- <Field data-invalid={isInvalid}>
73
+ <Field data-field={field.name} data-invalid={isInvalid}>
75
74
  {label && (
76
75
  <FieldLabel htmlFor={field.name}>
77
76
  {label}
@@ -1,23 +1,22 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import type { ComponentProps, ReactNode } from "react"
3
11
  import {
4
12
  Field,
5
13
  FieldContent,
6
14
  FieldDescription,
7
15
  FieldError,
8
16
  FieldLabel,
9
- } from "@zeno-lib/ui/field"
10
- import { Slider } from "@zeno-lib/ui/slider"
11
- import type { ComponentProps, ReactNode } from "react"
12
-
13
- import { describedBy } from "../lib/aria"
14
- import { useFieldContext } from "../lib/contexts"
17
+ } from "@/components/ui/field"
18
+ import { Slider } from "@/components/ui/slider"
15
19
  import { RequiredIndicator } from "../lib/required-indicator"
16
- import {
17
- useHideFieldErrors,
18
- useIsFieldRequired,
19
- useIsInvalid,
20
- } from "../lib/use-is-invalid"
21
20
 
22
21
  type SliderValue = number | number[]
23
22
 
@@ -56,7 +55,7 @@ function SliderField({
56
55
  const readout = formatValue && value !== undefined ? formatValue(value) : null
57
56
 
58
57
  return (
59
- <Field data-invalid={isInvalid}>
58
+ <Field data-field={field.name} data-invalid={isInvalid}>
60
59
  {(label || readout) && (
61
60
  <FieldContent className="flex-row items-center justify-between">
62
61
  {label && (
@@ -1,10 +1,9 @@
1
1
  "use client"
2
2
 
3
- import { Button } from "@zeno-lib/ui/button"
4
- import { Spinner } from "@zeno-lib/ui/spinner"
3
+ import { useFormContext } from "@zeno-lib/forms/lib/contexts"
5
4
  import type { ComponentProps } from "react"
6
-
7
- import { useFormContext } from "../lib/contexts"
5
+ import { Button } from "@/components/ui/button"
6
+ import { Spinner } from "@/components/ui/spinner"
8
7
 
9
8
  type SubmitButtonProps = Omit<ComponentProps<typeof Button>, "type">
10
9
 
@@ -1,23 +1,22 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import type { ComponentProps, ReactNode } from "react"
3
11
  import {
4
12
  Field,
5
13
  FieldContent,
6
14
  FieldDescription,
7
15
  FieldError,
8
16
  FieldLabel,
9
- } from "@zeno-lib/ui/field"
10
- import { Switch } from "@zeno-lib/ui/switch"
11
- import type { ComponentProps, ReactNode } from "react"
12
-
13
- import { describedBy } from "../lib/aria"
14
- import { useFieldContext } from "../lib/contexts"
17
+ } from "@/components/ui/field"
18
+ import { Switch } from "@/components/ui/switch"
15
19
  import { RequiredIndicator } from "../lib/required-indicator"
16
- import {
17
- useHideFieldErrors,
18
- useIsFieldRequired,
19
- useIsInvalid,
20
- } from "../lib/use-is-invalid"
21
20
 
22
21
  type SwitchFieldProps = Omit<
23
22
  ComponentProps<typeof Switch>,
@@ -45,7 +44,11 @@ function SwitchField({
45
44
  const isRequired = required ?? schemaRequired
46
45
 
47
46
  return (
48
- <Field data-invalid={isInvalid} orientation="horizontal">
47
+ <Field
48
+ data-field={field.name}
49
+ data-invalid={isInvalid}
50
+ orientation="horizontal"
51
+ >
49
52
  <FieldContent>
50
53
  {label && (
51
54
  <FieldLabel htmlFor={field.name}>
@@ -1,23 +1,22 @@
1
1
  "use client"
2
2
 
3
+ import { describedBy } from "@zeno-lib/forms/lib/aria"
4
+ import { useFieldContext } from "@zeno-lib/forms/lib/contexts"
5
+ import {
6
+ useHideFieldErrors,
7
+ useIsFieldRequired,
8
+ useIsInvalid,
9
+ } from "@zeno-lib/forms/lib/use-is-invalid"
10
+ import { Children, type ComponentProps, type ReactNode } from "react"
3
11
  import {
4
12
  Field,
5
13
  FieldDescription,
6
14
  FieldError,
7
15
  FieldLabel,
8
- } from "@zeno-lib/ui/field"
9
- import { InputGroup, InputGroupTextarea } from "@zeno-lib/ui/input-group"
10
- import { Textarea } from "@zeno-lib/ui/textarea"
11
- import { Children, type ComponentProps, type ReactNode } from "react"
12
-
13
- import { describedBy } from "../lib/aria"
14
- import { useFieldContext } from "../lib/contexts"
16
+ } from "@/components/ui/field"
17
+ import { InputGroup, InputGroupTextarea } from "@/components/ui/input-group"
18
+ import { Textarea } from "@/components/ui/textarea"
15
19
  import { RequiredIndicator } from "../lib/required-indicator"
16
- import {
17
- useHideFieldErrors,
18
- useIsFieldRequired,
19
- useIsInvalid,
20
- } from "../lib/use-is-invalid"
21
20
 
22
21
  type TextAreaFieldProps = Omit<
23
22
  ComponentProps<typeof Textarea>,
@@ -63,7 +62,7 @@ function TextAreaField({
63
62
  }
64
63
 
65
64
  return (
66
- <Field data-invalid={isInvalid}>
65
+ <Field data-field={field.name} data-invalid={isInvalid}>
67
66
  {label && (
68
67
  <FieldLabel htmlFor={field.name}>
69
68
  {label}
@@ -0,0 +1,51 @@
1
+ "use client"
2
+
3
+ import type { AnyFormApi } from "@tanstack/react-form"
4
+ import type { ComponentProps, FormEvent, ReactNode } from "react"
5
+
6
+ import { FormProvider as RawFormProvider, useFormContext } from "./lib/contexts"
7
+
8
+ type FormProviderProps = {
9
+ children: ReactNode
10
+ form: { handleSubmit: () => unknown }
11
+ }
12
+
13
+ function FormProvider({ children, form }: FormProviderProps) {
14
+ return (
15
+ <RawFormProvider value={form as AnyFormApi}>{children}</RawFormProvider>
16
+ )
17
+ }
18
+
19
+ type FormProps = Omit<ComponentProps<"form">, "onSubmit">
20
+
21
+ function Form({ children, className, ...props }: FormProps) {
22
+ const form = useFormContext()
23
+ return (
24
+ <form
25
+ className={className}
26
+ noValidate
27
+ onSubmit={async (event: FormEvent<HTMLFormElement>) => {
28
+ event.preventDefault()
29
+ event.stopPropagation()
30
+ const node = event.currentTarget
31
+ await Promise.resolve(form.handleSubmit()).catch(() => undefined)
32
+ if (!form.state.isValid) {
33
+ // First invalid control in *this* form; a group root (radio group,
34
+ // slider) hands focus to its first tabbable child.
35
+ const invalid = node.querySelector<HTMLElement>(
36
+ '[aria-invalid="true"]'
37
+ )
38
+ const targets = invalid
39
+ ? [invalid, ...invalid.querySelectorAll<HTMLElement>("*")]
40
+ : []
41
+ targets.find((el) => el.tabIndex >= 0)?.focus()
42
+ }
43
+ }}
44
+ {...props}
45
+ >
46
+ {children}
47
+ </form>
48
+ )
49
+ }
50
+
51
+ export { Form, FormProvider }
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ /* biome-ignore-all lint/performance/noBarrelFile: single npm entry for the headless form API. */
2
+
3
+ export { createZenoForm } from "./create-zeno-form"
4
+ export { Form, FormProvider } from "./form-element"
5
+ export { applyValidationError } from "./lib/apply-validation-error"
6
+ export { useFieldContext, useFormContext } from "./lib/contexts"
7
+ export {
8
+ useHideFieldErrors,
9
+ useIsFieldRequired,
10
+ useIsInvalid,
11
+ } from "./lib/use-is-invalid"
12
+ export { type FieldMessage, ValidationError } from "./lib/validation-error"
13
+ export { blurThenChangeLogic } from "./lib/validation-logic"
14
+ export type { ValidationMode } from "./lib/validation-modes"
@@ -1,6 +1,5 @@
1
1
  import type { AnyFormApi } from "@tanstack/react-form"
2
- import { describe, expect, test, vi } from "@zeno-lib/vitest"
3
-
2
+ import { describe, expect, test, vi } from "vitest"
4
3
  import { applyValidationError } from "./apply-validation-error"
5
4
  import { ValidationError } from "./validation-error"
6
5
 
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
 
3
- import { cn } from "@zeno-lib/ui/lib/utils"
4
3
  import type { ComponentProps } from "react"
4
+ import { cn } from "@/lib/utils"
5
5
 
6
6
  type RequiredIndicatorProps = ComponentProps<"span">
7
7
 
@@ -1,6 +1,5 @@
1
- import { describe, expect, test } from "@zeno-lib/vitest"
1
+ import { describe, expect, test } from "vitest"
2
2
  import { z } from "zod"
3
-
4
3
  import { deepMergeDefaults, extractZodDefaults } from "./schema-defaults"
5
4
 
6
5
  describe("extractZodDefaults — primitives", () => {