/** * Input — headless proprietary primitive. * * Client component (consumes `PermissionContext` + `AuditContext` via * `useContext`). Wraps the native `` with: * - Permission gating via `can('edit', resource, attrs)`. The three * modes collapse cleanly for form fields: `disabled` → native * disabled, `readOnly` → native readOnly (visible, focus-reachable, * non-mutating), `hidden` → returns null. * - Canonical `input:change` audit emission on blur (not per-keystroke — * that would drown the stream; blur is the semantic "I'm done typing" * boundary). Also `input:blur` when a consumer needs the signal * separately. `permission:denied` on blocked edits in `readOnly`. * - `data-oshon-primitive="input"` + `data-permission-state` styling hooks. * * Proprietary rather than Radix-wrapped because native `` behavior * is narrow — label wiring (htmlFor), form association, constraint * validation, ARIA defaults all come free. See ADR-001 for the * "proprietary vs. Radix" rubric (same rubric applied to Button). */ import type { InputHTMLAttributes } from 'react'; import { type PermissionContext } from '../context.js'; type NativeInputProps = Omit, 'disabled' | 'readOnly' | 'aria-invalid'>; export interface InputProps extends NativeInputProps { /** * Disable the input. Renders with the native `disabled` attribute so * screen readers and keyboard users get consistent signal. No change / * blur audit events fire while disabled. */ disabled?: boolean; /** * Non-mutating but still interactive. Renders with native `readOnly` * so the field is focus-reachable, copy-friendly, and announced as * read-only by assistive tech. Change events are silently dropped. */ readOnly?: boolean; /** * Marks the field as invalid for a11y. `true` → `aria-invalid="true"`. * The visual layer surfaces the error styling; primitive only ensures * correct ARIA. */ invalid?: boolean; /** * Per-instance permission override. Merges over the ambient * `PermissionContext`. Example: `permissions={{ mode: 'hidden' }}` * switches this one instance to render-as-null when denied. */ permissions?: Partial; /** * Resource name passed to `permissions.can('edit', resource, attrs)`. * Default `'input'`. Consumers override for specific semantics, e.g. * `resource="field:ssn"` for a sensitive data field. */ resource?: string; /** * Attribute bag forwarded to `permissions.can(..., attrs)` for * attribute-based access control. Primitives never invent values here * — the consumer supplies them. */ permissionAttrs?: Record; } /** * Headless input. Accessible `` with: * - `disabled` / `readOnly` / `aria-invalid` / `aria-disabled` * synchronised * - Permission gating via `can('edit', resource, attrs)`: * - `mode='disabled'` (default) — renders native `disabled` * - `mode='readOnly'` — renders native `readOnly` (visible, * focus-reachable, non-mutating) * - `mode='hidden'` — returns null * - Canonical `input:change` + `input:blur` audit on blur (granted); * `permission:denied` when the user attempts to mutate a * readOnly-gated field * - `data-oshon-primitive="input"` styling hook * - `data-permission-state="denied"` styling hook under any deny mode * that keeps the affordance visible * - No visual styling — consumers supply their own className / styles. * * Keyboard: native browser behavior — Tab focuses, typing mutates. */ export declare const Input: import("react").ForwardRefExoticComponent>; export {}; //# sourceMappingURL=input.d.cts.map