@fabio.caffarello/react-design-system 4.0.0 → 4.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.
@@ -33,6 +33,27 @@ export interface AutocompleteProps {
33
33
  */
34
34
  "aria-labelledby"?: string;
35
35
  id?: string;
36
+ /**
37
+ * Name of the form field (issue #225). When set, the component renders
38
+ * a synchronized `<input type="hidden" name={name}>` carrying the
39
+ * **selected option value** (not the visible search text), so the
40
+ * Autocomplete participates in native form submission exactly like a
41
+ * `<select name>` — a `<form method="GET">` picks up `name=value` with
42
+ * no `onChange`/router wiring on the consumer side. This is the
43
+ * form-native integration the brasil-a-vera filter bars need.
44
+ *
45
+ * Caveat: the component is interactive (`"use client"`), so the hidden
46
+ * field is populated once hydrated — it is NOT a pre-hydration no-JS
47
+ * fallback. For a true zero-JS fallback, pair it with a `<noscript>`
48
+ * native `<select name>`.
49
+ */
50
+ name?: string;
51
+ /**
52
+ * Associates the hidden field with a form by id (the native `form`
53
+ * attribute), for when the Autocomplete renders outside the `<form>`
54
+ * it submits to. No effect unless `name` is also set.
55
+ */
56
+ form?: string;
36
57
  }
37
58
  /**
38
59
  * Autocomplete Component
@@ -1,24 +1,22 @@
1
- import type { InputHTMLAttributes, ReactNode } from "react";
2
- export type InputSize = "sm" | "md" | "lg";
3
- export type InputVariant = "default" | "outlined" | "filled";
4
- export type InputState = "default" | "error" | "success";
5
- export interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
6
- label?: ReactNode;
7
- error?: boolean;
8
- success?: boolean;
9
- helperText?: string;
10
- size?: InputSize;
11
- variant?: InputVariant;
12
- leftIcon?: ReactNode;
13
- rightIcon?: ReactNode;
1
+ import type { InputBaseProps } from "./InputBase";
2
+ export type { InputSize, InputVariant, InputState } from "./InputBase";
3
+ export interface InputProps extends Omit<InputBaseProps, "rightSlot"> {
14
4
  showClearButton?: boolean;
15
5
  onClear?: () => void;
16
6
  }
17
7
  /**
18
8
  * Input Component
19
9
  *
20
- * A styled text input component with label, error/success states, icons, and clear button.
21
- * Uses Composite Pattern when combined with Label and ErrorMessage.
10
+ * The interactive text input: everything `InputBase` renders, plus the
11
+ * client-only affordances that require React state the password
12
+ * visibility toggle (`type="password"`), the clear button
13
+ * (`showClearButton`), and the `useId` auto-id fallback. It **composes**
14
+ * `InputBase` (issue #224): the presentational shell lives once in
15
+ * `InputBase`, and `Input` layers the stateful affixes on top, passing
16
+ * the resolved `id`, the toggled `type`, and its buttons via `rightSlot`.
17
+ *
18
+ * Need a server-renderable / native-form input with no client state?
19
+ * Import `InputBase` from `@fabio.caffarello/react-design-system/server`.
22
20
  *
23
21
  * @example
24
22
  * ```tsx
@@ -0,0 +1,52 @@
1
+ import type { InputHTMLAttributes, ReactNode } from "react";
2
+ export type InputSize = "sm" | "md" | "lg";
3
+ export type InputVariant = "default" | "outlined" | "filled";
4
+ export type InputState = "default" | "error" | "success";
5
+ export interface InputBaseProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
6
+ label?: ReactNode;
7
+ error?: boolean;
8
+ success?: boolean;
9
+ helperText?: string;
10
+ size?: InputSize;
11
+ variant?: InputVariant;
12
+ leftIcon?: ReactNode;
13
+ rightIcon?: ReactNode;
14
+ /**
15
+ * Raw trailing-affix slot rendered inside the input's right edge with
16
+ * full interactivity (no `pointer-events-none`). The interactive
17
+ * `Input` injects its password-toggle / clear buttons here; consumers
18
+ * can use it for a static suffix (a unit, a badge). When omitted,
19
+ * `rightIcon` renders instead with the muted decorative treatment.
20
+ */
21
+ rightSlot?: ReactNode;
22
+ }
23
+ /**
24
+ * InputBase
25
+ *
26
+ * The **presentational core** of the text input — label, the `<input>`
27
+ * itself, decorative left/right icons, the trailing-affix slot, and the
28
+ * helper/error line. It holds **no React client state** (no `useState`,
29
+ * `useId`, `useCallback`), so it is server-safe and ships from the
30
+ * `./server` entry (issue #224).
31
+ *
32
+ * The interactive `Input` (default export of this folder) composes
33
+ * `InputBase`, owning the password-toggle state, the clear button, and
34
+ * the `useId` auto-id fallback — it passes the resolved `id`, the
35
+ * toggled `type`, and its affix buttons (`rightSlot`) down. Use
36
+ * `InputBase` directly for server-rendered / native-form inputs where
37
+ * none of that interactivity is needed (`<form method="GET">` filters,
38
+ * RSC pages).
39
+ *
40
+ * Accessible name: pass `id` when you pass `label` so the `<label
41
+ * htmlFor>` binds — `InputBase` does NOT auto-generate an id (that needs
42
+ * `useId`, which would make it client). A dev-only warning fires when a
43
+ * `label` is given without an `id`.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * // Server component / native form — zero client state.
48
+ * <InputBase id="q" name="q" placeholder="Buscar…" />
49
+ * ```
50
+ */
51
+ declare const InputBase: import("react").ForwardRefExoticComponent<InputBaseProps & import("react").RefAttributes<HTMLInputElement>>;
52
+ export default InputBase;
@@ -1,2 +1,4 @@
1
1
  export { default } from "./Input";
2
2
  export type { InputProps, InputSize, InputVariant, InputState } from "./Input";
3
+ export { default as InputBase } from "./InputBase";
4
+ export type { InputBaseProps } from "./InputBase";
@@ -1,11 +1,15 @@
1
1
  export { default as Badge } from "./primitives/Badge/Badge";
2
2
  export type { BadgeProps, BadgeSize, BadgeStyle, BadgeVariant, } from "./primitives/Badge/Badge";
3
+ export { default as Button } from "./primitives/Button/Button";
4
+ export type { ButtonProps, ButtonSize, ButtonVariant, } from "./primitives/Button/Button";
3
5
  export { default as Chip } from "./primitives/Chip/Chip";
4
6
  export type { ChipProps, ChipSize, ChipVariant } from "./primitives/Chip/Chip";
5
7
  export { default as ErrorMessage } from "./primitives/ErrorMessage/ErrorMessage";
6
8
  export type { ErrorMessageProps } from "./primitives/ErrorMessage/ErrorMessage";
7
9
  export { default as Info } from "./primitives/Info/Info";
8
10
  export type { InfoProps } from "./primitives/Info/Info";
11
+ export { default as InputBase } from "./primitives/Input/InputBase";
12
+ export type { InputBaseProps, InputSize, InputVariant, InputState, } from "./primitives/Input/InputBase";
9
13
  export { default as Label } from "./primitives/Label/Label";
10
14
  export { default as Progress } from "./primitives/Progress/Progress";
11
15
  export type { ProgressProps, ProgressSize, ProgressVariant, } from "./primitives/Progress/Progress";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fabio.caffarello/react-design-system",
3
3
  "private": false,
4
- "version": "4.0.0",
4
+ "version": "4.2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",