UNPKG

@payfit/unity-components

Version:

159 lines (158 loc) 6.34 kB
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>>;