@arcfusionz/arc-primitive-ui 0.0.0 → 0.2.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 (136) hide show
  1. package/dist/components/AILoader/AILoader.d.ts +32 -0
  2. package/dist/components/AILoader/AILoader.js +157 -0
  3. package/dist/components/AILoader/index.d.ts +2 -0
  4. package/dist/components/AILoader/index.js +2 -0
  5. package/dist/components/Accordion/Accordion.d.ts +96 -0
  6. package/dist/components/Accordion/Accordion.js +149 -0
  7. package/dist/components/Accordion/index.d.ts +2 -0
  8. package/dist/components/Accordion/index.js +2 -0
  9. package/dist/components/Avatar/Avatar.d.ts +152 -0
  10. package/dist/components/Avatar/Avatar.js +216 -0
  11. package/dist/components/Avatar/index.d.ts +2 -0
  12. package/dist/components/Avatar/index.js +2 -0
  13. package/dist/components/Badge/Badge.d.ts +87 -0
  14. package/dist/components/Badge/Badge.js +118 -0
  15. package/dist/components/Badge/index.d.ts +2 -0
  16. package/dist/components/Badge/index.js +2 -0
  17. package/dist/components/Breadcrumb/Breadcrumb.d.ts +109 -0
  18. package/dist/components/Breadcrumb/Breadcrumb.js +182 -0
  19. package/dist/components/Breadcrumb/index.d.ts +2 -0
  20. package/dist/components/Breadcrumb/index.js +2 -0
  21. package/dist/components/Button/Button.d.ts +57 -0
  22. package/dist/components/Button/Button.js +177 -0
  23. package/dist/components/Button/index.d.ts +2 -0
  24. package/dist/components/Button/index.js +2 -0
  25. package/dist/components/Calendar/Calendar.d.ts +140 -0
  26. package/dist/components/Calendar/Calendar.js +468 -0
  27. package/dist/components/Calendar/index.d.ts +2 -0
  28. package/dist/components/Calendar/index.js +2 -0
  29. package/dist/components/Checkbox/Checkbox.d.ts +60 -0
  30. package/dist/components/Checkbox/Checkbox.js +129 -0
  31. package/dist/components/Checkbox/index.d.ts +2 -0
  32. package/dist/components/Checkbox/index.js +2 -0
  33. package/dist/components/Combobox/Combobox.d.ts +251 -0
  34. package/dist/components/Combobox/Combobox.js +354 -0
  35. package/dist/components/Combobox/index.d.ts +2 -0
  36. package/dist/components/Combobox/index.js +2 -0
  37. package/dist/components/ContextMenu/ContextMenu.d.ts +129 -0
  38. package/dist/components/ContextMenu/ContextMenu.js +93 -0
  39. package/dist/components/ContextMenu/index.d.ts +2 -0
  40. package/dist/components/ContextMenu/index.js +2 -0
  41. package/dist/components/DatePicker/DatePicker.d.ts +109 -0
  42. package/dist/components/DatePicker/DatePicker.js +145 -0
  43. package/dist/components/DatePicker/index.d.ts +2 -0
  44. package/dist/components/DatePicker/index.js +2 -0
  45. package/dist/components/DateRangePicker/DateRangePicker.d.ts +107 -0
  46. package/dist/components/DateRangePicker/DateRangePicker.js +161 -0
  47. package/dist/components/DateRangePicker/index.d.ts +2 -0
  48. package/dist/components/DateRangePicker/index.js +2 -0
  49. package/dist/components/Dialog/Dialog.d.ts +112 -0
  50. package/dist/components/Dialog/Dialog.js +141 -0
  51. package/dist/components/Dialog/index.d.ts +2 -0
  52. package/dist/components/Dialog/index.js +2 -0
  53. package/dist/components/Drawer/Drawer.d.ts +188 -0
  54. package/dist/components/Drawer/Drawer.js +268 -0
  55. package/dist/components/Drawer/index.d.ts +2 -0
  56. package/dist/components/Drawer/index.js +2 -0
  57. package/dist/components/Field/Field.d.ts +123 -0
  58. package/dist/components/Field/Field.js +241 -0
  59. package/dist/components/Field/FieldContext.d.ts +43 -0
  60. package/dist/components/Field/FieldContext.js +28 -0
  61. package/dist/components/Field/index.d.ts +3 -0
  62. package/dist/components/Field/index.js +3 -0
  63. package/dist/components/Fieldset/Fieldset.d.ts +43 -0
  64. package/dist/components/Fieldset/Fieldset.js +48 -0
  65. package/dist/components/Fieldset/index.d.ts +2 -0
  66. package/dist/components/Fieldset/index.js +2 -0
  67. package/dist/components/Form/Form.d.ts +54 -0
  68. package/dist/components/Form/Form.js +57 -0
  69. package/dist/components/Form/index.d.ts +2 -0
  70. package/dist/components/Form/index.js +2 -0
  71. package/dist/components/Input/Input.d.ts +64 -0
  72. package/dist/components/Input/Input.js +111 -0
  73. package/dist/components/Input/index.d.ts +2 -0
  74. package/dist/components/Input/index.js +2 -0
  75. package/dist/components/Menu/Menu.d.ts +212 -0
  76. package/dist/components/Menu/Menu.js +255 -0
  77. package/dist/components/Menu/index.d.ts +2 -0
  78. package/dist/components/Menu/index.js +2 -0
  79. package/dist/components/Popover/Popover.d.ts +122 -0
  80. package/dist/components/Popover/Popover.js +116 -0
  81. package/dist/components/Popover/index.d.ts +2 -0
  82. package/dist/components/Popover/index.js +2 -0
  83. package/dist/components/Progress/Progress.d.ts +87 -0
  84. package/dist/components/Progress/Progress.js +73 -0
  85. package/dist/components/Progress/index.d.ts +2 -0
  86. package/dist/components/Progress/index.js +2 -0
  87. package/dist/components/Radio/Radio.d.ts +65 -0
  88. package/dist/components/Radio/Radio.js +93 -0
  89. package/dist/components/Radio/index.d.ts +2 -0
  90. package/dist/components/Radio/index.js +2 -0
  91. package/dist/components/Select/Select.d.ts +136 -0
  92. package/dist/components/Select/Select.js +219 -0
  93. package/dist/components/Select/index.d.ts +2 -0
  94. package/dist/components/Select/index.js +2 -0
  95. package/dist/components/Skeleton/Skeleton.d.ts +39 -0
  96. package/dist/components/Skeleton/Skeleton.js +44 -0
  97. package/dist/components/Skeleton/index.d.ts +2 -0
  98. package/dist/components/Skeleton/index.js +2 -0
  99. package/dist/components/Stepper/Stepper.d.ts +161 -0
  100. package/dist/components/Stepper/Stepper.js +344 -0
  101. package/dist/components/Stepper/index.d.ts +2 -0
  102. package/dist/components/Stepper/index.js +2 -0
  103. package/dist/components/Switch/Switch.d.ts +56 -0
  104. package/dist/components/Switch/Switch.js +87 -0
  105. package/dist/components/Switch/index.d.ts +2 -0
  106. package/dist/components/Switch/index.js +2 -0
  107. package/dist/components/Table/Table.d.ts +116 -0
  108. package/dist/components/Table/Table.js +143 -0
  109. package/dist/components/Table/index.d.ts +2 -0
  110. package/dist/components/Table/index.js +2 -0
  111. package/dist/components/Tabs/Tabs.d.ts +116 -0
  112. package/dist/components/Tabs/Tabs.js +158 -0
  113. package/dist/components/Tabs/index.d.ts +2 -0
  114. package/dist/components/Tabs/index.js +2 -0
  115. package/dist/components/Timeline/Timeline.d.ts +137 -0
  116. package/dist/components/Timeline/Timeline.js +243 -0
  117. package/dist/components/Timeline/index.d.ts +2 -0
  118. package/dist/components/Timeline/index.js +2 -0
  119. package/dist/components/Toast/Toast.d.ts +135 -0
  120. package/dist/components/Toast/Toast.js +314 -0
  121. package/dist/components/Toast/index.d.ts +2 -0
  122. package/dist/components/Toast/index.js +2 -0
  123. package/dist/components/Tooltip/Tooltip.d.ts +104 -0
  124. package/dist/components/Tooltip/Tooltip.js +95 -0
  125. package/dist/components/Tooltip/index.d.ts +2 -0
  126. package/dist/components/Tooltip/index.js +2 -0
  127. package/dist/components/Typography/Typography.d.ts +38 -0
  128. package/dist/components/Typography/Typography.js +53 -0
  129. package/dist/components/Typography/index.d.ts +2 -0
  130. package/dist/components/Typography/index.js +2 -0
  131. package/dist/index.d.ts +66 -3398
  132. package/dist/index.js +34 -5343
  133. package/dist/lib/cn.d.ts +6 -0
  134. package/dist/lib/cn.js +9 -0
  135. package/package.json +6 -2
  136. package/src/styles/theme.css +341 -341
@@ -0,0 +1,43 @@
1
+ //#region src/components/Field/FieldContext.d.ts
2
+ /**
3
+ * Control wiring a connected `Field` provides to the form control inside it.
4
+ * The shape mirrors React Hook Form's `field` object from `useController`,
5
+ * kept structural so consumers of the context never import react-hook-form.
6
+ */
7
+ interface FieldControlProps {
8
+ /** Field name registered with the form. */
9
+ name: string;
10
+ /** Current field value from form state. */
11
+ value: unknown;
12
+ /** Whether react-hook-form marked the field disabled (form- or field-level). */
13
+ disabled?: boolean;
14
+ /** Change handler — accepts either a change event or a raw value. */
15
+ onChange: (eventOrValue: unknown) => void;
16
+ /** Blur handler — marks the field as touched. */
17
+ onBlur: () => void;
18
+ /** Ref callback used for focus management (e.g. focus-first-error on submit). */
19
+ ref: (instance: unknown) => void;
20
+ }
21
+ /**
22
+ * Control wiring published by the closest connected `Field`, or `null` when
23
+ * the component is not inside one. `Input` consumes this automatically; use
24
+ * it to connect controls that don't yet, e.g. a Select:
25
+ *
26
+ * function PlanSelect(props: SelectProps<string>) {
27
+ * const control = useFieldControl();
28
+ * return (
29
+ * <Select
30
+ * value={control?.value as string}
31
+ * onValueChange={control?.onChange}
32
+ * inputRef={control?.ref}
33
+ * {...props}
34
+ * />
35
+ * );
36
+ * }
37
+ *
38
+ * React Hook Form's `onChange` accepts raw values, so Base UI `onValueChange`
39
+ * callbacks can be passed straight through.
40
+ */
41
+ declare function useFieldControl(): FieldControlProps | null;
42
+ //#endregion
43
+ export { FieldControlProps, useFieldControl };
@@ -0,0 +1,28 @@
1
+ import { createContext, useContext } from "react";
2
+ //#region src/components/Field/FieldContext.ts
3
+ const FieldContext = createContext(null);
4
+ /**
5
+ * Control wiring published by the closest connected `Field`, or `null` when
6
+ * the component is not inside one. `Input` consumes this automatically; use
7
+ * it to connect controls that don't yet, e.g. a Select:
8
+ *
9
+ * function PlanSelect(props: SelectProps<string>) {
10
+ * const control = useFieldControl();
11
+ * return (
12
+ * <Select
13
+ * value={control?.value as string}
14
+ * onValueChange={control?.onChange}
15
+ * inputRef={control?.ref}
16
+ * {...props}
17
+ * />
18
+ * );
19
+ * }
20
+ *
21
+ * React Hook Form's `onChange` accepts raw values, so Base UI `onValueChange`
22
+ * callbacks can be passed straight through.
23
+ */
24
+ function useFieldControl() {
25
+ return useContext(FieldContext)?.control ?? null;
26
+ }
27
+ //#endregion
28
+ export { FieldContext, useFieldControl };
@@ -0,0 +1,3 @@
1
+ import { Field, FieldDescription, FieldDescriptionProps, FieldError, FieldErrorProps, FieldItem, FieldItemProps, FieldLabel, FieldLabelProps, FieldLabelVariantsOptions, FieldOrientation, FieldProps, FieldValidity, FieldValidityProps, fieldLabelVariants } from "./Field.js";
2
+ import { FieldControlProps, useFieldControl } from "./FieldContext.js";
3
+ export { Field, type FieldControlProps, FieldDescription, type FieldDescriptionProps, FieldError, type FieldErrorProps, FieldItem, type FieldItemProps, FieldLabel, type FieldLabelProps, type FieldLabelVariantsOptions, type FieldOrientation, type FieldProps, FieldValidity, type FieldValidityProps, fieldLabelVariants, useFieldControl };
@@ -0,0 +1,3 @@
1
+ import { useFieldControl } from "./FieldContext.js";
2
+ import { Field, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, fieldLabelVariants } from "./Field.js";
3
+ export { Field, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity, fieldLabelVariants, useFieldControl };
@@ -0,0 +1,43 @@
1
+ import { ComponentPropsWithoutRef, HTMLAttributes } from "react";
2
+ import { Fieldset } from "@base-ui/react/fieldset";
3
+ //#region src/components/Fieldset/Fieldset.d.ts
4
+ interface FieldsetProps extends Omit<ComponentPropsWithoutRef<typeof Fieldset.Root>, "className"> {
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Groups related fields under one shared `FieldsetLegend` — required for
9
+ * radio and checkbox groups (WCAG 1.3.1), useful for form sections like
10
+ * "Billing details". Renders a native `<fieldset>`, so `disabled` disables
11
+ * every control inside it at once; with React Hook Form, note that disabling
12
+ * here is visual/interactive only — schema validation still runs, so also
13
+ * disable or exclude those fields in the form when they shouldn't block
14
+ * submission.
15
+ */
16
+ declare const Fieldset$1: import("react").ForwardRefExoticComponent<FieldsetProps & import("react").RefAttributes<HTMLFieldSetElement>>;
17
+ type FieldsetLegendVariant = "section" | "label";
18
+ interface FieldsetLegendProps extends Omit<ComponentPropsWithoutRef<typeof Fieldset.Legend>, "className"> {
19
+ /**
20
+ * `section` (default) styles the legend as a form-section heading;
21
+ * `label` matches `FieldLabel` for radio/checkbox groups, so the group
22
+ * caption reads like the labels of the fields around it.
23
+ */
24
+ variant?: FieldsetLegendVariant;
25
+ className?: string;
26
+ }
27
+ /**
28
+ * The fieldset's caption, automatically associated with the group for
29
+ * assistive technology. Keep it short — some screen readers repeat the
30
+ * legend before every control in the group.
31
+ */
32
+ declare const FieldsetLegend: import("react").ForwardRefExoticComponent<FieldsetLegendProps & import("react").RefAttributes<HTMLDivElement>>;
33
+ interface FieldsetDescriptionProps extends Omit<HTMLAttributes<HTMLParagraphElement>, "className"> {
34
+ className?: string;
35
+ }
36
+ /**
37
+ * Supporting copy for the whole group, placed right after the legend.
38
+ * Visible text content read in sequence — unlike `FieldDescription` it is
39
+ * not wired into any control's `aria-describedby`.
40
+ */
41
+ declare const FieldsetDescription: import("react").ForwardRefExoticComponent<FieldsetDescriptionProps & import("react").RefAttributes<HTMLParagraphElement>>;
42
+ //#endregion
43
+ export { Fieldset$1 as Fieldset, FieldsetDescription, FieldsetDescriptionProps, FieldsetLegend, FieldsetLegendProps, FieldsetLegendVariant, FieldsetProps };
@@ -0,0 +1,48 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { forwardRef } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { Fieldset } from "@base-ui/react/fieldset";
5
+ //#region src/components/Fieldset/Fieldset.tsx
6
+ /**
7
+ * Groups related fields under one shared `FieldsetLegend` — required for
8
+ * radio and checkbox groups (WCAG 1.3.1), useful for form sections like
9
+ * "Billing details". Renders a native `<fieldset>`, so `disabled` disables
10
+ * every control inside it at once; with React Hook Form, note that disabling
11
+ * here is visual/interactive only — schema validation still runs, so also
12
+ * disable or exclude those fields in the form when they shouldn't block
13
+ * submission.
14
+ */
15
+ const Fieldset$1 = forwardRef(({ className, ...rest }, ref) => /* @__PURE__ */ jsx(Fieldset.Root, {
16
+ ref,
17
+ className: cn("flex min-w-0 flex-col gap-4", className),
18
+ ...rest
19
+ }));
20
+ Fieldset$1.displayName = "Fieldset";
21
+ const legendVariantClasses = {
22
+ section: "font-heading text-lg font-semibold text-foreground",
23
+ label: "font-sans text-sm font-medium text-foreground"
24
+ };
25
+ /**
26
+ * The fieldset's caption, automatically associated with the group for
27
+ * assistive technology. Keep it short — some screen readers repeat the
28
+ * legend before every control in the group.
29
+ */
30
+ const FieldsetLegend = forwardRef(({ variant = "section", className, ...rest }, ref) => /* @__PURE__ */ jsx(Fieldset.Legend, {
31
+ ref,
32
+ className: cn(legendVariantClasses[variant], "data-disabled:opacity-50", className),
33
+ ...rest
34
+ }));
35
+ FieldsetLegend.displayName = "FieldsetLegend";
36
+ /**
37
+ * Supporting copy for the whole group, placed right after the legend.
38
+ * Visible text content read in sequence — unlike `FieldDescription` it is
39
+ * not wired into any control's `aria-describedby`.
40
+ */
41
+ const FieldsetDescription = forwardRef(({ className, ...rest }, ref) => /* @__PURE__ */ jsx("p", {
42
+ ref,
43
+ className: cn("font-sans text-sm text-muted-foreground in-data-disabled:opacity-50", className),
44
+ ...rest
45
+ }));
46
+ FieldsetDescription.displayName = "FieldsetDescription";
47
+ //#endregion
48
+ export { Fieldset$1 as Fieldset, FieldsetDescription, FieldsetLegend };
@@ -0,0 +1,2 @@
1
+ import { Fieldset, FieldsetDescription, FieldsetDescriptionProps, FieldsetLegend, FieldsetLegendProps, FieldsetLegendVariant, FieldsetProps } from "./Fieldset.js";
2
+ export { Fieldset, FieldsetDescription, type FieldsetDescriptionProps, FieldsetLegend, type FieldsetLegendProps, type FieldsetLegendVariant, type FieldsetProps };
@@ -0,0 +1,2 @@
1
+ import { Fieldset, FieldsetDescription, FieldsetLegend } from "./Fieldset.js";
2
+ export { Fieldset, FieldsetDescription, FieldsetLegend };
@@ -0,0 +1,54 @@
1
+ import { ComponentPropsWithoutRef, ReactNode, Ref } from "react";
2
+ import { FieldValues, SubmitErrorHandler, SubmitHandler, UseFormReturn } from "react-hook-form";
3
+ import { Form } from "@base-ui/react/form";
4
+ //#region src/components/Form/Form.d.ts
5
+ type BaseFormProps = ComponentPropsWithoutRef<typeof Form>;
6
+ interface FormProps<TFieldValues extends FieldValues = FieldValues, TTransformedValues = TFieldValues> extends Omit<BaseFormProps, "className"> {
7
+ /**
8
+ * The `useForm` return value. Providing it switches the form to React Hook
9
+ * Form mode: children get the form context (so `<Field name="…">` connects
10
+ * with no extra props), submission runs through `handleSubmit`, and native
11
+ * constraint validation is turned off (`noValidate`) so the schema is the
12
+ * single source of truth. Omit it for a native Base UI form (constraint
13
+ * validation, the `errors` server-error map, `onFormSubmit`).
14
+ */
15
+ form?: UseFormReturn<TFieldValues, any, TTransformedValues>;
16
+ /**
17
+ * Called with the parsed values when submission passes validation — with a
18
+ * Zod resolver this is the schema's output type. React Hook Form focuses
19
+ * the first invalid control when validation fails (`shouldFocusError`).
20
+ */
21
+ onValidSubmit?: SubmitHandler<TTransformedValues>;
22
+ /** Called with the field errors when submission fails validation. */
23
+ onInvalidSubmit?: SubmitErrorHandler<TFieldValues>;
24
+ className?: string;
25
+ }
26
+ interface FormComponent {
27
+ <TFieldValues extends FieldValues = FieldValues, TTransformedValues = TFieldValues>(props: FormProps<TFieldValues, TTransformedValues> & {
28
+ ref?: Ref<HTMLFormElement>;
29
+ }): ReactNode;
30
+ displayName?: string;
31
+ }
32
+ /**
33
+ * The form element for both worlds. With `form={useForm(…)}` it becomes the
34
+ * React Hook Form shell — provider, `handleSubmit`, and `noValidate` in one:
35
+ *
36
+ * const schema = z.object({ email: z.email("Enter a valid email") });
37
+ * const form = useForm({ resolver: zodResolver(schema), mode: "onTouched" });
38
+ *
39
+ * <Form form={form} onValidSubmit={(data) => save(data)}>
40
+ * <Field name="email">
41
+ * <FieldLabel>Email</FieldLabel>
42
+ * <Input type="email" autoComplete="email" />
43
+ * <FieldError />
44
+ * </Field>
45
+ * <Button type="submit">Save</Button>
46
+ * </Form>
47
+ *
48
+ * Without `form` it is Base UI's native form: constraint validation drives
49
+ * `FieldError` via `match`, `errors` maps server errors onto fields by name,
50
+ * and `onFormSubmit` receives values as a plain object.
51
+ */
52
+ declare const Form$1: FormComponent;
53
+ //#endregion
54
+ export { Form$1 as Form, FormProps };
@@ -0,0 +1,57 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { forwardRef } from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { FormProvider } from "react-hook-form";
5
+ import { Form } from "@base-ui/react/form";
6
+ //#region src/components/Form/Form.tsx
7
+ const formClasses = "flex w-full min-w-0 flex-col gap-6";
8
+ function noopSubmit() {}
9
+ const FormImpl = forwardRef(({ form, onValidSubmit, onInvalidSubmit, onSubmit, noValidate, className, ...rest }, ref) => {
10
+ if (form == null) return /* @__PURE__ */ jsx(Form, {
11
+ ref,
12
+ onSubmit,
13
+ noValidate,
14
+ className: cn(formClasses, className),
15
+ ...rest
16
+ });
17
+ const handleSubmit = (event) => {
18
+ onSubmit?.(event);
19
+ if (event.defaultPrevented) return;
20
+ form.handleSubmit(onValidSubmit ?? noopSubmit, onInvalidSubmit)(event);
21
+ };
22
+ return /* @__PURE__ */ jsx(FormProvider, {
23
+ ...form,
24
+ children: /* @__PURE__ */ jsx(Form, {
25
+ ref,
26
+ onSubmit: handleSubmit,
27
+ noValidate: noValidate ?? true,
28
+ className: cn(formClasses, className),
29
+ ...rest
30
+ })
31
+ });
32
+ });
33
+ FormImpl.displayName = "Form";
34
+ /**
35
+ * The form element for both worlds. With `form={useForm(…)}` it becomes the
36
+ * React Hook Form shell — provider, `handleSubmit`, and `noValidate` in one:
37
+ *
38
+ * const schema = z.object({ email: z.email("Enter a valid email") });
39
+ * const form = useForm({ resolver: zodResolver(schema), mode: "onTouched" });
40
+ *
41
+ * <Form form={form} onValidSubmit={(data) => save(data)}>
42
+ * <Field name="email">
43
+ * <FieldLabel>Email</FieldLabel>
44
+ * <Input type="email" autoComplete="email" />
45
+ * <FieldError />
46
+ * </Field>
47
+ * <Button type="submit">Save</Button>
48
+ * </Form>
49
+ *
50
+ * Without `form` it is Base UI's native form: constraint validation drives
51
+ * `FieldError` via `match`, `errors` maps server errors onto fields by name,
52
+ * and `onFormSubmit` receives values as a plain object.
53
+ */
54
+ const Form$1 = FormImpl;
55
+ Form$1.displayName = "Form";
56
+ //#endregion
57
+ export { Form$1 as Form };
@@ -0,0 +1,2 @@
1
+ import { Form, FormProps } from "./Form.js";
2
+ export { Form, type FormProps };
@@ -0,0 +1,2 @@
1
+ import { Form } from "./Form.js";
2
+ export { Form };
@@ -0,0 +1,64 @@
1
+ import { ComponentPropsWithoutRef, HTMLAttributes } from "react";
2
+ import { Input } from "@base-ui/react/input";
3
+ //#region src/components/Input/Input.d.ts
4
+ type InputSize = "sm" | "md" | "lg";
5
+ interface InputVariantsOptions {
6
+ size?: InputSize;
7
+ className?: string;
8
+ }
9
+ /**
10
+ * Class list for an element styled as a standalone Input — for input-shaped
11
+ * elements that aren't this component (a `<textarea>`, a fake search box that
12
+ * opens a command palette) so every text control shares one look. Inside an
13
+ * `InputGroup` the group owns the frame; these classes are for standalone use.
14
+ */
15
+ declare function inputVariants({ size, className }?: InputVariantsOptions): string;
16
+ type BaseInputProps = ComponentPropsWithoutRef<typeof Input>;
17
+ interface InputProps extends Omit<BaseInputProps, "className" | "size"> {
18
+ /** Control height. `sm` (32px) meets the WCAG 2.5.8 AA target-size floor; prefer `md`/`lg` for touch-first surfaces. Inside an `InputGroup` the group's `size` wins. */
19
+ size?: InputSize;
20
+ /** The native `size` attribute (visible width in characters) — renamed because `size` selects the control height. */
21
+ htmlSize?: number;
22
+ /** Marks the input invalid (`aria-invalid` + destructive styling) when validation is wired manually. Composed `Field`s set this state for you via `data-invalid`. */
23
+ invalid?: boolean;
24
+ className?: string;
25
+ }
26
+ /**
27
+ * Native text input built on Base UI's Input. Full width by default — size
28
+ * it via the container. Inside a `Field` it inherits labelling, description
29
+ * and error wiring plus state data-attributes automatically; inside a
30
+ * *connected* Field (React Hook Form) the value, change/blur handlers, and
31
+ * focus ref are wired for you too — passing `value`, `defaultValue`,
32
+ * `onChange`, or `name` yourself takes back manual control (don't also
33
+ * `register` the same name: the Field already registered it). Standalone
34
+ * max-performance registration `{...form.register("name")}` works as usual.
35
+ * Fields that collect data about the user must pass the matching
36
+ * `autocomplete` token (WCAG 1.3.5).
37
+ */
38
+ declare const Input$1: import("react").ForwardRefExoticComponent<InputProps & import("react").RefAttributes<HTMLInputElement>>;
39
+ interface InputGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, "className"> {
40
+ /** Frame height, mirroring Input sizes. The Input inside inherits it. */
41
+ size?: InputSize;
42
+ className?: string;
43
+ }
44
+ /**
45
+ * Frame that seats decorations next to an `Input` — icons, text affixes like
46
+ * `$` or `.com`, or interactive addons — inside one shared border with a
47
+ * single focus ring. Compose `InputGroupAddon`(s) and one `Input` in visual
48
+ * order; the input goes bare and the group takes over its frame, including
49
+ * invalid/disabled/read-only states. Works inside `Field` unchanged.
50
+ */
51
+ declare const InputGroup: import("react").ForwardRefExoticComponent<InputGroupProps & import("react").RefAttributes<HTMLDivElement>>;
52
+ interface InputGroupAddonProps extends Omit<HTMLAttributes<HTMLDivElement>, "className"> {
53
+ className?: string;
54
+ }
55
+ /**
56
+ * A decoration slot inside `InputGroup` — place it before or after the
57
+ * `Input` in the children. Addon content sits outside the input's accessible
58
+ * name: mark purely decorative content (icons, unit text repeated in the
59
+ * label) with `aria-hidden`, and never hide interactive addons — a clear or
60
+ * show-password `Button` must stay in the accessibility tree.
61
+ */
62
+ declare const InputGroupAddon: import("react").ForwardRefExoticComponent<InputGroupAddonProps & import("react").RefAttributes<HTMLDivElement>>;
63
+ //#endregion
64
+ export { Input$1 as Input, InputGroup, InputGroupAddon, InputGroupAddonProps, InputGroupProps, InputProps, InputSize, InputVariantsOptions, inputVariants };
@@ -0,0 +1,111 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { FieldContext } from "../Field/FieldContext.js";
3
+ import { createContext, forwardRef, useContext, useMemo } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { Input } from "@base-ui/react/input";
6
+ //#region src/components/Input/Input.tsx
7
+ const inputBaseClasses = "block w-full min-w-0 appearance-none rounded-md border border-border bg-background font-sans text-foreground placeholder:text-muted-foreground transition-colors duration-150 hover:border-slate-300 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-invalid:border-destructive data-invalid:hover:border-destructive data-invalid:focus-visible:outline-destructive aria-invalid:border-destructive aria-invalid:hover:border-destructive aria-invalid:focus-visible:outline-destructive [&[readonly]]:bg-surface disabled:pointer-events-none disabled:opacity-50 data-disabled:pointer-events-none data-disabled:opacity-50 file:me-3 file:h-full file:cursor-pointer file:border-0 file:bg-transparent file:font-sans file:text-sm file:font-medium file:text-foreground";
8
+ const inputSizeClasses = {
9
+ sm: "h-8 px-2.5 text-sm any-pointer-coarse:text-base",
10
+ md: "h-10 px-3 text-sm any-pointer-coarse:text-base",
11
+ lg: "h-12 px-3.5 text-base"
12
+ };
13
+ /**
14
+ * Class list for an element styled as a standalone Input — for input-shaped
15
+ * elements that aren't this component (a `<textarea>`, a fake search box that
16
+ * opens a command palette) so every text control shares one look. Inside an
17
+ * `InputGroup` the group owns the frame; these classes are for standalone use.
18
+ */
19
+ function inputVariants({ size = "md", className } = {}) {
20
+ return cn(inputBaseClasses, inputSizeClasses[size], className);
21
+ }
22
+ const bareInputClasses = "h-full w-full min-w-0 flex-1 appearance-none rounded-none border-0 bg-transparent p-0 font-sans text-inherit placeholder:text-muted-foreground outline-none disabled:pointer-events-none file:me-3 file:h-full file:cursor-pointer file:border-0 file:bg-transparent file:font-sans file:text-sm file:font-medium file:text-foreground";
23
+ function composeRefs(...refs) {
24
+ return (node) => {
25
+ for (const ref of refs) if (typeof ref === "function") ref(node);
26
+ else if (ref != null) ref.current = node;
27
+ };
28
+ }
29
+ /**
30
+ * Native text input built on Base UI's Input. Full width by default — size
31
+ * it via the container. Inside a `Field` it inherits labelling, description
32
+ * and error wiring plus state data-attributes automatically; inside a
33
+ * *connected* Field (React Hook Form) the value, change/blur handlers, and
34
+ * focus ref are wired for you too — passing `value`, `defaultValue`,
35
+ * `onChange`, or `name` yourself takes back manual control (don't also
36
+ * `register` the same name: the Field already registered it). Standalone
37
+ * max-performance registration `{...form.register("name")}` works as usual.
38
+ * Fields that collect data about the user must pass the matching
39
+ * `autocomplete` token (WCAG 1.3.5).
40
+ */
41
+ const Input$1 = forwardRef(({ size = "md", htmlSize, invalid, type, name, value, defaultValue, onChange, onBlur, disabled, required, className, ...rest }, ref) => {
42
+ const fieldContext = useContext(FieldContext);
43
+ const groupSize = useContext(InputGroupContext);
44
+ const adapter = fieldContext?.control ?? null;
45
+ const wired = adapter != null && !(value !== void 0 || defaultValue !== void 0 || onChange !== void 0 || name !== void 0);
46
+ const isFile = type === "file";
47
+ const requiredState = required ?? (fieldContext?.required ? true : void 0);
48
+ return /* @__PURE__ */ jsx(Input, {
49
+ ref: useMemo(() => wired ? composeRefs(ref, adapter.ref) : ref, [
50
+ wired,
51
+ ref,
52
+ adapter?.ref
53
+ ]),
54
+ type,
55
+ size: htmlSize,
56
+ name: wired ? adapter.name : name,
57
+ disabled: disabled ?? (wired ? adapter.disabled : void 0),
58
+ value: wired && !isFile ? adapter.value ?? "" : value,
59
+ defaultValue,
60
+ onChange: wired ? (event) => adapter.onChange(event) : onChange,
61
+ onBlur: (event) => {
62
+ onBlur?.(event);
63
+ if (wired) adapter.onBlur();
64
+ },
65
+ required: wired ? void 0 : requiredState,
66
+ "aria-required": wired && requiredState ? true : void 0,
67
+ "aria-invalid": invalid || void 0,
68
+ className: cn(groupSize != null ? bareInputClasses : inputVariants({ size }), className),
69
+ ...rest
70
+ });
71
+ });
72
+ Input$1.displayName = "Input";
73
+ const InputGroupContext = createContext(null);
74
+ const groupBaseClasses = "flex w-full min-w-0 items-center rounded-md border border-border bg-background font-sans text-foreground transition-colors duration-150 hover:border-slate-300 focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring has-data-invalid:border-destructive has-data-invalid:hover:border-destructive has-data-invalid:focus-within:outline-destructive has-aria-invalid:border-destructive has-aria-invalid:hover:border-destructive has-aria-invalid:focus-within:outline-destructive has-[input[readonly]]:bg-surface has-[input:disabled]:pointer-events-none has-[input:disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
75
+ const groupSizeClasses = {
76
+ sm: "h-8 gap-1.5 px-2.5 text-sm any-pointer-coarse:text-base",
77
+ md: "h-10 gap-2 px-3 text-sm any-pointer-coarse:text-base",
78
+ lg: "h-12 gap-2 px-3.5 text-base [&_svg:not([class*='size-'])]:size-5"
79
+ };
80
+ /**
81
+ * Frame that seats decorations next to an `Input` — icons, text affixes like
82
+ * `$` or `.com`, or interactive addons — inside one shared border with a
83
+ * single focus ring. Compose `InputGroupAddon`(s) and one `Input` in visual
84
+ * order; the input goes bare and the group takes over its frame, including
85
+ * invalid/disabled/read-only states. Works inside `Field` unchanged.
86
+ */
87
+ const InputGroup = forwardRef(({ size = "md", className, ...rest }, ref) => /* @__PURE__ */ jsx(InputGroupContext.Provider, {
88
+ value: size,
89
+ children: /* @__PURE__ */ jsx("div", {
90
+ ref,
91
+ className: cn(groupBaseClasses, groupSizeClasses[size], className),
92
+ ...rest
93
+ })
94
+ }));
95
+ InputGroup.displayName = "InputGroup";
96
+ const addonClasses = "flex shrink-0 select-none items-center gap-1.5 text-muted-foreground";
97
+ /**
98
+ * A decoration slot inside `InputGroup` — place it before or after the
99
+ * `Input` in the children. Addon content sits outside the input's accessible
100
+ * name: mark purely decorative content (icons, unit text repeated in the
101
+ * label) with `aria-hidden`, and never hide interactive addons — a clear or
102
+ * show-password `Button` must stay in the accessibility tree.
103
+ */
104
+ const InputGroupAddon = forwardRef(({ className, ...rest }, ref) => /* @__PURE__ */ jsx("div", {
105
+ ref,
106
+ className: cn(addonClasses, className),
107
+ ...rest
108
+ }));
109
+ InputGroupAddon.displayName = "InputGroupAddon";
110
+ //#endregion
111
+ export { Input$1 as Input, InputGroup, InputGroupAddon, inputVariants };
@@ -0,0 +1,2 @@
1
+ import { Input, InputGroup, InputGroupAddon, InputGroupAddonProps, InputGroupProps, InputProps, InputSize, InputVariantsOptions, inputVariants } from "./Input.js";
2
+ export { Input, InputGroup, InputGroupAddon, type InputGroupAddonProps, type InputGroupProps, type InputProps, type InputSize, type InputVariantsOptions, inputVariants };
@@ -0,0 +1,2 @@
1
+ import { Input, InputGroup, InputGroupAddon, inputVariants } from "./Input.js";
2
+ export { Input, InputGroup, InputGroupAddon, inputVariants };