@payfit/unity-components
Version:
159 lines (158 loc) • 6.34 kB
TypeScript
import { default as React, PropsWithChildren } from 'react';
import { InlineFieldGroupMode } from './InlineFieldGroup.context.js';
/**
* Imperative handle for InlineFieldGroup component.
* Provides methods for programmatic control when needed for advanced use cases.
*/
export interface InlineFieldGroupHandle {
/**
* Focuses the first invalid field in the edit view.
* Useful for custom validation error handling.
*/
focusFirstInvalidField: () => void;
/**
* Exits edit mode programmatically.
*/
exitEditMode: () => void;
/**
* Enters edit mode programmatically.
*/
enterEditMode: () => void;
}
export interface InlineFieldGroupProps extends PropsWithChildren {
/**
* Controlled mode value. When provided, the component operates in controlled mode.
*/
mode?: InlineFieldGroupMode;
/**
* Default mode value for uncontrolled mode.
* @default 'read'
*/
defaultMode?: InlineFieldGroupMode;
/**
* Callback fired when mode changes.
*/
onModeChange?: (mode: InlineFieldGroupMode) => void;
/**
* Callback to intercept and potentially prevent mode changes.
* Return `false` to prevent the mode transition.
* Return `true` or `undefined` to allow the transition.
*/
shouldModeChange?: (fromMode: InlineFieldGroupMode, toMode: InlineFieldGroupMode) => boolean | undefined;
/**
* Whether the component is in a loading state (e.g., during async save).
*/
isLoading?: boolean;
/**
* Optional className for custom styling
*/
className?: string;
/**
* Optional aria-label for the form element.
* If not provided, aria-labelledby will reference the header title.
*/
'aria-label'?: string;
/**
* Indicates whether the component or element should track and respond to focus containment.
* When set to true, the focus is constrained within the component, preventing focus from
* moving outside its boundaries.
* @default false
*/
containFocus?: boolean;
/**
* Success message to announce when save succeeds.
* If not provided, no success announcement is made.
*/
successMessage?: string;
/**
* Error message to announce when save or validation fails.
* If not provided, generic validation errors are announced.
*/
errorMessage?: string;
/**
* Custom label for the edit button.
* @default "Edit" (translated)
*/
editLabel?: string;
/**
* Custom label for the save button.
* @default "Save" (translated)
*/
saveLabel?: string;
/**
* Custom label for the cancel button.
* @default "Cancel" (translated)
*/
cancelLabel?: string;
/**
* Optional callback fired when the edit button is clicked.
* This is called before entering edit mode and is useful for analytics or side effects.
*/
onEditPress?: () => void;
/**
* Optional callback fired when the save button is clicked.
* This is called before form submission and is useful for analytics or side effects.
* Note: Form submission is handled via the form's onSubmit configuration.
*/
onSavePress?: () => void;
/**
* Optional callback fired when the cancel button is clicked.
* This is called before canceling and is useful for analytics or side effects.
* The form will be reset and edit mode exited automatically.
*/
onCancelPress?: () => void;
}
/**
* InlineFieldGroup enables group-level inline editing with read/edit mode switching.
* It integrates with TanStack Form for validation and state management, providing
* a complete pattern for displaying data in read mode and editing it in edit mode.
* The component handles the full edit lifecycle: mode transitions, form submission,
* validation error handling, and accessibility announcements.
* @example
* ```tsx
* import { useTanstackUnityForm } from '@payfit/unity-components'
*
* function ContactForm() {
* const form = useTanstackUnityForm({
* defaultValues: { email: 'user@example.com', phone: '+1234567890' },
* onSubmit: async ({ value }) => {
* await saveContact(value)
* }
* })
*
* return (
* <form.AppForm>
* <form.InlineFieldGroup successMessage="Contact saved!">
* <form.InlineFieldGroupHeader title="Contact Information" />
* <form.InlineFieldGroupReadView>
* <DefinitionList>
* <DefinitionItem term="Email" description={form.state.values.email} />
* </DefinitionList>
* </form.InlineFieldGroupReadView>
* <form.InlineFieldGroupEditView legend="Edit contact">
* <form.AppField name="email">
* {field => <field.TextField label="Email" />}
* </form.AppField>
* </form.InlineFieldGroupEditView>
* </form.InlineFieldGroup>
* </form.AppForm>
* )
* }
* ```
* @remarks
* - The component automatically exits edit mode on successful form submission
* - Press Escape to cancel editing and reset form values
* - Focus moves to the first form field when entering edit mode
* - Focus returns to the edit button when exiting edit mode (only if focus hasn't moved elsewhere)
* - Focus is retained under a scope when in edit mode, to prevent users for leaving unfinished changes
* - Use `shouldModeChange` to intercept and conditionally prevent mode transitions
* - Use `successMessage` and `errorMessage` for accessible announcements via live regions
* @see {@link InlineFieldGroupProps} for all available props
* @see {@link InlineFieldGroupHandle} for imperative handle methods
* @see {@link InlineFieldGroupHeader} for the header component with action buttons
* @see {@link InlineFieldGroupReadView} for read mode content
* @see {@link InlineFieldGroupEditView} for edit mode form fields
* @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/components/inline-field-group GitHub}
* @see Developer docs in {@link https://unity-components.payfit.io/?path=/docs/forms-reference-inlinefieldgroup--docs unity-components.payfit.io}
*/
export declare const InlineFieldGroup: React.ForwardRefExoticComponent<InlineFieldGroupProps & React.RefAttributes<InlineFieldGroupHandle>>;