goobs-frontend
Version:
A comprehensive React-based libary for building modern web applications
125 lines • 5.46 kB
TypeScript
import { default as React, ReactNode } from 'react';
import { FieldStyleOverrides } from './types';
export interface FieldShellSlot {
/**
* Stable id from React's useId(). Spread onto the input/button as
* `id={inputId}` so the auto-rendered <label htmlFor=…> links to it.
*/
inputId: string;
/**
* Stable id for the helper/error region. The `inputAriaProps`
* already wires this via aria-describedby — exposed here for cases
* where the consumer needs it directly (e.g. multi-element fields
* like DateRange where two inputs share one helper region).
*/
helperId: string;
/**
* Pre-built ARIA prop bag. Spread onto your input/button:
*
* <input {...inputAriaProps} />
*
* Sets aria-required, aria-disabled, aria-invalid, and
* aria-describedby (when error/helperText is present).
*/
inputAriaProps: {
'aria-required'?: boolean;
'aria-disabled'?: boolean;
'aria-invalid'?: boolean;
'aria-describedby'?: string;
};
}
export interface FieldShellProps {
/**
* Visible label. Rendered inside a real `<label htmlFor={inputId}>`
* so `getByLabel(/foo/i)` and screenreader announcement both work.
* Pass null/undefined to render no label (rare — bare inputs in
* data tables, for example).
*/
label?: ReactNode | undefined;
/**
* Marks the field required. Renders the required indicator next to
* the label and sets aria-required on the input via inputAriaProps.
* Top-level for ergonomic API; mirrored from `styles.required` if
* present (consumers can set either; top-level wins).
*/
required?: boolean | undefined;
/**
* Disabled state. Sets aria-disabled on the wrapper (CSS dims +
* pointer-events:none). The consumer's input also needs the native
* `disabled` attribute — pass `disabled` separately to your input.
*/
disabled?: boolean | undefined;
/**
* Error state. When a string is set, the helper region renders the
* error text with role="alert" + aria-live="polite", and the input
* gets aria-invalid="true" via inputAriaProps. Pass `true` (boolean)
* for error styling without a message — the helper region collapses
* to its info text in that case but the field still styles as
* invalid.
*/
error?: string | boolean | undefined;
/**
* Helper text shown below the input. Replaced by `error` when set.
* The region exists in the DOM at all times (with min-height so the
* layout doesn't jump on validation flips).
*/
helperText?: ReactNode | undefined;
/**
* Stable test selector. Emitted as `data-field="<value>"` on the
* wrapper — typically the canonical entity name (`"category"`,
* `"contract"`).
*/
dataField?: string | undefined;
/**
* Stable test selector. Emitted as `data-field-name="<value>"` on
* the wrapper — typically the form-input name (`"customerName"`,
* `"address1"`). Used by Playwright `[data-field-name="…"]`
* locators.
*/
dataFieldName?: string | undefined;
/**
* Form-engine binding key. When the shell is rendered inside a `<Form>` and
* `name` is set, the shell auto-derives its `error` (from the engine) and
* `required` (from the schema) for this field — unless the consumer passes
* an explicit `error`/`required`, which always win. Also emitted as
* `data-field-name` when `dataFieldName` is not set. Outside a `<Form>` this
* prop is inert and the shell behaves byte-for-byte as before.
*/
name?: string | undefined;
/**
* Marks the field as visually "filled" (has a value) — emitted as
* `data-filled` on the wrapper for CSS float-label / styling hooks. Purely
* presentational; defaults to undefined (attribute omitted).
*/
filled?: boolean | undefined;
/**
* Visual state for the data-state attribute. Drives focus/error CSS
* selectors. Most consumers don't pass this — leave it undefined and
* CSS pseudo-classes (`:focus-within`, `[aria-invalid]`) do the
* work. Pass an explicit value for cases CSS can't detect, like
* `'open'` on a controlled dropdown popover.
*/
state?: 'idle' | 'focus' | 'open' | 'error' | undefined;
/**
* Per-instance overrides. Most properties become inline styles on
* the wrapper; `theme`/`disabled`/`required`/`requiredIndicatorText`/
* `helperTextType` drive ARIA + data attributes; CSS-variable keys
* (`--field-bg`, etc.) override the module's theme tokens for that
* instance.
*/
styles?: FieldStyleOverrides | undefined;
/**
* The input/button/popover-trigger element. Receives the slot with
* inputId, helperId, and inputAriaProps. Spread inputAriaProps onto
* your element so ARIA wiring doesn't get out of sync.
*/
children: (slot: FieldShellSlot) => ReactNode;
}
declare const FieldShell: React.FC<FieldShellProps>;
export default FieldShell;
export type { FieldStyleOverrides, FieldTheme } from './types';
export { type FieldChangeHandler, type FieldValidityHandler, type FieldValidator, } from './types';
export { getRequiredProps, validateRequired } from './utils';
export { useEscape, useArrowKeyNav } from './keyboard';
export type { ArrowKeyNavOptions } from './keyboard';
//# sourceMappingURL=index.d.ts.map