@payfit/unity-components 2.2.8 → 2.3.1

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.
@@ -17,6 +17,12 @@ export interface DefinitionItemProps {
17
17
  * Children of the component.
18
18
  */
19
19
  children?: ReactNode;
20
+ /**
21
+ * The vertical alignment of the term.
22
+ * Note: Normally, you should not need to set this property, if you follow the design guidelines.
23
+ * @default 'undefined'
24
+ */
25
+ verticalAlign?: 'start' | 'center';
20
26
  }
21
27
  /**
22
28
  * DefinitionItem displays a term (`dt`) and its description (`dd`) within a `DefinitionList`.
@@ -40,7 +40,4 @@ export interface CircularIconButtonProps extends Omit<AriaButtonProps, 'classNam
40
40
  isDisabled?: boolean;
41
41
  className?: string;
42
42
  }
43
- export declare function CircularIconButton(props: CircularIconButtonProps): import("react/jsx-runtime").JSX.Element;
44
- export declare namespace CircularIconButton {
45
- var displayName: string;
46
- }
43
+ export declare const CircularIconButton: import('react').ForwardRefExoticComponent<CircularIconButtonProps & import('react').RefAttributes<HTMLButtonElement>>;
@@ -1,11 +1,12 @@
1
- import { jsx as e, jsxs as c } from "react/jsx-runtime";
2
- import { uyTv as h } from "@payfit/unity-themes";
3
- import { Button as x, Pressable as z } from "react-aria-components";
4
- import I from "../../hooks/use-id.js";
5
- import { Icon as d } from "../icon/Icon.js";
6
- import { Spinner as y } from "../spinner/Spinner.js";
7
- import { Tooltip as b } from "../tooltip/Tooltip.js";
8
- const N = h({
1
+ import { jsx as e, jsxs as d } from "react/jsx-runtime";
2
+ import { forwardRef as z } from "react";
3
+ import { uyTv as I } from "@payfit/unity-themes";
4
+ import { Button as N, Pressable as B } from "react-aria-components";
5
+ import L from "../../hooks/use-id.js";
6
+ import { Icon as y } from "../icon/Icon.js";
7
+ import { Spinner as b } from "../spinner/Spinner.js";
8
+ import { Tooltip as f } from "../tooltip/Tooltip.js";
9
+ const j = I({
9
10
  base: [
10
11
  "uy:rounded-circle uy:cursor-pointer uy:flex uy:items-center uy:justify-center uy:transition-colors",
11
12
  'uy:disabled:cursor-not-allowed uy:disabled:text-content-neutral-disabled uy:disabled:data-[hovered="true"]:bg-transparent',
@@ -46,34 +47,36 @@ const N = h({
46
47
  size: "default",
47
48
  color: "content.neutral.low"
48
49
  }
49
- });
50
- function B(f) {
51
- const v = I(), {
52
- onPress: o,
50
+ }), D = z((m, o) => {
51
+ const v = L(), {
52
+ type: p,
53
+ onPress: s,
53
54
  icon: u,
54
- color: m,
55
+ color: g,
55
56
  size: l,
56
57
  isLoading: t,
57
58
  title: a,
58
- isDisabled: s,
59
- asElement: p = "default",
60
- className: g,
61
- "aria-labelledby": w,
62
- ...i
63
- } = f, r = `icon-button-label-${v}`, n = N({ class: g, color: m, size: l });
64
- return p === "button" ? /* @__PURE__ */ e(b, { title: a, children: /* @__PURE__ */ c(
65
- x,
59
+ isDisabled: i,
60
+ asElement: w = "default",
61
+ className: h,
62
+ "aria-labelledby": x,
63
+ ...n
64
+ } = m, r = `icon-button-label-${v}`, c = j({ class: h, color: g, size: l });
65
+ return w === "button" ? /* @__PURE__ */ e(f, { title: a, children: /* @__PURE__ */ d(
66
+ N,
66
67
  {
68
+ ref: o,
67
69
  "data-dd-privacy": "allow",
68
- ...i,
69
- onPress: o,
70
- isDisabled: s || t,
71
- "aria-labelledby": w ?? r,
70
+ ...n,
71
+ type: p,
72
+ onPress: s,
73
+ isDisabled: i || t,
74
+ "aria-labelledby": x ?? r,
72
75
  "aria-busy": t,
73
- className: n,
76
+ className: c,
74
77
  children: [
75
- t ? /* @__PURE__ */ e(y, { size: "small", label: "Loading", color: "inherit" }) : /* @__PURE__ */ e(
76
- d,
78
+ t ? /* @__PURE__ */ e(b, { size: "small", label: "Loading", color: "inherit" }) : /* @__PURE__ */ e(
79
+ y,
77
80
  {
78
81
  src: u,
79
82
  size: l === "large" ? 24 : 20,
@@ -84,18 +87,19 @@ function B(f) {
84
87
  /* @__PURE__ */ e("span", { id: r, className: "uy:sr-only", children: a })
85
88
  ]
86
89
  }
87
- ) }) : /* @__PURE__ */ e(b, { title: a, children: /* @__PURE__ */ e(
88
- z,
90
+ ) }) : /* @__PURE__ */ e(f, { title: a, children: /* @__PURE__ */ e(
91
+ B,
89
92
  {
93
+ ref: o,
90
94
  "data-dd-privacy": "allow",
91
- ...i,
92
- onPress: o,
93
- isDisabled: s || t,
95
+ ...n,
96
+ onPress: s,
97
+ isDisabled: i || t,
94
98
  "aria-labelledby": r,
95
99
  "aria-busy": t,
96
- children: /* @__PURE__ */ c("div", { role: "button", className: n, children: [
97
- t ? /* @__PURE__ */ e(y, { size: "small", label: "Loading", color: "inherit" }) : /* @__PURE__ */ e(
98
- d,
100
+ children: /* @__PURE__ */ d("div", { role: "button", className: c, children: [
101
+ t ? /* @__PURE__ */ e(b, { size: "small", label: "Loading", color: "inherit" }) : /* @__PURE__ */ e(
102
+ y,
99
103
  {
100
104
  src: u,
101
105
  size: l === "large" ? 24 : 20,
@@ -107,9 +111,9 @@ function B(f) {
107
111
  ] })
108
112
  }
109
113
  ) });
110
- }
111
- B.displayName = "CircularIconButton";
114
+ });
115
+ D.displayName = "CircularIconButton";
112
116
  export {
113
- B as CircularIconButton,
114
- N as circularIconButton
117
+ D as CircularIconButton,
118
+ j as circularIconButton
115
119
  };
@@ -1,5 +1,5 @@
1
1
  import { UnityIcon } from '@payfit/unity-icons';
2
- import { AriaRole } from 'react';
2
+ import { AriaRole, ButtonHTMLAttributes } from 'react';
3
3
  import { IconButtonGhost, IconButtonPrimary, IconButtonSecondary } from './IconButton.variants.js';
4
4
  interface IconButtonBaseProps {
5
5
  /** Label used to describe the action of the button */
@@ -12,6 +12,8 @@ interface IconButtonBaseProps {
12
12
  iconRole?: AriaRole;
13
13
  /** className to add to the button */
14
14
  className?: string;
15
+ /** The button type */
16
+ type?: ButtonHTMLAttributes<HTMLButtonElement>['type'];
15
17
  }
16
18
  interface IconButtonVariantsPrimaryProps extends IconButtonBaseProps, Omit<IconButtonPrimary, 'variant' | 'color'>, Required<Pick<IconButtonPrimary, 'variant' | 'color'>> {
17
19
  }
@@ -0,0 +1,21 @@
1
+ import { RefObject } from 'react';
2
+ export type InlineFieldMode = 'read' | 'edit';
3
+ export interface InlineFieldContextValue {
4
+ /** Current mode: read or edit */
5
+ mode: InlineFieldMode;
6
+ /** Switch to edit mode */
7
+ enterEditMode: () => void;
8
+ /** Exit edit mode (cancel or save) */
9
+ exitEditMode: () => void;
10
+ /** Unique ID for the field (for aria attributes) */
11
+ fieldId: string;
12
+ /** Whether the field is currently loading (saving) */
13
+ isLoading?: boolean;
14
+ /** Ref to the edit view container for focus management */
15
+ editViewRef: RefObject<HTMLDivElement>;
16
+ /** The ID for the edit view container (for aria-controls) */
17
+ editViewId: string;
18
+ triggerRef: RefObject<HTMLButtonElement>;
19
+ }
20
+ export declare const InlineFieldContext: import('react').Context<InlineFieldContextValue | undefined>;
21
+ export declare function useInlineField(): InlineFieldContextValue | undefined;
@@ -0,0 +1,10 @@
1
+ import { createContext as n, useContext as t } from "react";
2
+ const e = n(void 0);
3
+ e.displayName = "InlineFieldContext";
4
+ function o() {
5
+ return t(e);
6
+ }
7
+ export {
8
+ e as InlineFieldContext,
9
+ o as useInlineField
10
+ };
@@ -0,0 +1,91 @@
1
+ import { ReactNode } from 'react';
2
+ import { InlineFieldMode } from './InlineField.context.js';
3
+ export interface InlineFieldProps {
4
+ /**
5
+ * The form field to display in edit mode.
6
+ */
7
+ children?: ReactNode;
8
+ /**
9
+ * Controlled mode value. When provided, the component operates in controlled mode.
10
+ */
11
+ mode?: InlineFieldMode;
12
+ /**
13
+ * Default mode value for uncontrolled mode.
14
+ * `@default` 'read'
15
+ */
16
+ defaultMode?: InlineFieldMode;
17
+ /**
18
+ * Callback fired when mode changes.
19
+ */
20
+ onModeChange?: (mode: InlineFieldMode) => void;
21
+ /**
22
+ * Whether the field is currently loading (saving).
23
+ */
24
+ isLoading?: boolean;
25
+ /**
26
+ * Callback to determine if mode should change.
27
+ * Return `false` to prevent the mode transition.
28
+ * Return `true` or `undefined` to allow the transition.
29
+ */
30
+ shouldModeChange?: (fromMode: InlineFieldMode, toMode: InlineFieldMode) => boolean | undefined;
31
+ }
32
+ /**
33
+ * InlineField enables individual field inline editing with read/edit mode switching.
34
+ * It integrates with TanStack Form for validation and state management, providing
35
+ * a pattern for displaying a value in read mode and editing it in edit mode.
36
+ * The component handles the edit lifecycle: mode transitions, form submission,
37
+ * validation error handling, and accessibility announcements.
38
+ * @example
39
+ * ```tsx
40
+ * import { useTanstackUnityForm } from '@payfit/unity-components'
41
+ *
42
+ * function EmailField() {
43
+ * const form = useTanstackUnityForm({
44
+ * defaultValues: { email: 'user@example.com' },
45
+ * onSubmit: async ({ value }) => {
46
+ * await saveEmail(value)
47
+ * }
48
+ * })
49
+ *
50
+ * return (
51
+ * <form.AppForm>
52
+ * <DefinitionList>
53
+ * <form.AppField name="email">
54
+ * {field => (
55
+ * <field.InlineField>
56
+ * <field.InlineFieldReadView>
57
+ * <DefinitionItem
58
+ * term="Email"
59
+ * description={form.state.values.email}
60
+ * action={<field.InlineFieldEditTrigger />}
61
+ * />
62
+ * </field.InlineFieldReadView>
63
+ * <field.InlineFieldEditView successMessage="Email updated!">
64
+ * <field.TextField label="Email" isRequired />
65
+ * </field.InlineFieldEditView>
66
+ * </field.InlineField>
67
+ * )}
68
+ * </form.AppField>
69
+ * </DefinitionList>
70
+ * </form.AppForm>
71
+ * )
72
+ * }
73
+ * ```
74
+ * @remarks
75
+ * - The component automatically exits edit mode on successful form submission.
76
+ * - Press Escape to cancel editing and reset the field value.
77
+ * - Focus moves to the field when entering edit mode.
78
+ * - Focus returns to the edit button when exiting edit mode.
79
+ * - Focus is retained under a scope when in edit mode.
80
+ * - Use `shouldModeChange` to intercept and conditionally prevent mode transitions.
81
+ * - Use `successMessage` and `errorMessage` for accessible announcements via live regions.
82
+ * @see {@link InlineFieldProps} for all available props
83
+ * @see {@link InlineFieldReadView} for read mode content
84
+ * @see {@link InlineFieldEditView} for edit mode form fields
85
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/components/inline-field GitHub}
86
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/docs/forms-reference-inlinefield--docs unity-components.payfit.io}
87
+ */
88
+ export declare const InlineField: {
89
+ ({ children, mode: controlledMode, defaultMode, onModeChange, isLoading, shouldModeChange, }: InlineFieldProps): import("react/jsx-runtime").JSX.Element;
90
+ displayName: string;
91
+ };
@@ -0,0 +1,49 @@
1
+ import { jsx as R } from "react/jsx-runtime";
2
+ import { useRef as r, useId as b, useMemo as E, useCallback as M, useEffect as v } from "react";
3
+ import { useInlineFieldMode as w } from "./hooks/useInlineFieldMode.js";
4
+ import { InlineFieldContext as V } from "./InlineField.context.js";
5
+ const g = ({
6
+ children: m,
7
+ mode: a,
8
+ defaultMode: F,
9
+ onModeChange: x,
10
+ isLoading: o,
11
+ shouldModeChange: p
12
+ }) => {
13
+ const i = r(null), e = r(null), l = r(!0), { mode: t, enterEditMode: s, exitEditMode: d } = w({
14
+ mode: a,
15
+ defaultMode: F,
16
+ onModeChange: x,
17
+ shouldModeChange: p
18
+ }), n = `inline-field-${b()}`, c = `${n}__edit-view`, I = E(
19
+ () => ({
20
+ mode: t,
21
+ enterEditMode: s,
22
+ exitEditMode: d,
23
+ fieldId: n,
24
+ isLoading: o,
25
+ triggerRef: i,
26
+ editViewRef: e,
27
+ editViewId: c
28
+ }),
29
+ [t, s, d, n, o, c]
30
+ ), u = M(() => {
31
+ if (e.current) {
32
+ const f = e.current.querySelectorAll(
33
+ 'input, select, textarea, [tabindex]:not([tabindex="-1"])'
34
+ );
35
+ f.length > 0 && f[0].focus();
36
+ }
37
+ }, [e]);
38
+ return v(() => {
39
+ if (l.current) {
40
+ l.current = !1;
41
+ return;
42
+ }
43
+ t === "edit" ? u() : i.current && i.current.focus();
44
+ }, [t, u]), /* @__PURE__ */ R(V.Provider, { value: I, children: m });
45
+ };
46
+ g.displayName = "InlineField";
47
+ export {
48
+ g as InlineField
49
+ };
@@ -0,0 +1,46 @@
1
+ import { InlineFieldMode } from '../InlineField.context.js';
2
+ export interface UseInlineFieldModeProps {
3
+ /**
4
+ * Controlled mode value. When provided, the component operates in controlled mode.
5
+ */
6
+ mode?: InlineFieldMode;
7
+ /**
8
+ * Default mode value for uncontrolled mode.
9
+ * @default 'read'
10
+ */
11
+ defaultMode?: InlineFieldMode;
12
+ /**
13
+ * Callback fired when mode changes.
14
+ */
15
+ onModeChange?: (mode: InlineFieldMode) => void;
16
+ /**
17
+ * Callback to intercept and potentially prevent mode changes.
18
+ * Return `false` to prevent the mode transition.
19
+ * Return `true` or `undefined` to allow the transition.
20
+ */
21
+ shouldModeChange?: (fromMode: InlineFieldMode, toMode: InlineFieldMode) => boolean | undefined;
22
+ }
23
+ export interface UseInlineFieldModeReturn {
24
+ /** Current mode value */
25
+ mode: InlineFieldMode;
26
+ /** Switch to edit mode */
27
+ enterEditMode: () => void;
28
+ /** Exit edit mode (return to read mode) */
29
+ exitEditMode: () => void;
30
+ /** Check if component is in controlled mode */
31
+ isControlled: boolean;
32
+ }
33
+ /**
34
+ * Hook to manage the mode state (read/edit) for InlineField.
35
+ * Supports both controlled and uncontrolled modes, following the pattern
36
+ * established by NavGroup.tsx
37
+ * @param props - Configuration for the mode hook
38
+ * @param props.mode - Controlled mode value. When provided, the component operates in controlled mode.
39
+ * @param props.defaultMode - Default mode value for uncontrolled mode.
40
+ * @param props.onModeChange - Callback fired when mode changes.
41
+ * @param props.shouldModeChange - Callback to intercept and potentially prevent mode changes.
42
+ * Return `false` to prevent the mode transition.
43
+ * Return `true` or `undefined` to allow the transition.
44
+ * @returns Mode state and handlers
45
+ */
46
+ export declare function useInlineFieldMode({ mode: controlledMode, defaultMode, onModeChange, shouldModeChange, }: UseInlineFieldModeProps): UseInlineFieldModeReturn;
@@ -0,0 +1,27 @@
1
+ import { useState as m, useCallback as r } from "react";
2
+ function x({
3
+ mode: d,
4
+ defaultMode: c = "read",
5
+ onModeChange: s,
6
+ shouldModeChange: o
7
+ }) {
8
+ const [l, a] = m(c), t = d !== void 0, n = t ? d : l, e = r(
9
+ (i) => {
10
+ o && o(n, i) === !1 || (t || a(i), s?.(i));
11
+ },
12
+ [t, n, s, o]
13
+ ), f = r(() => {
14
+ e("edit");
15
+ }, [e]), u = r(() => {
16
+ e("read");
17
+ }, [e]);
18
+ return {
19
+ mode: n,
20
+ enterEditMode: f,
21
+ exitEditMode: u,
22
+ isControlled: t
23
+ };
24
+ }
25
+ export {
26
+ x as useInlineFieldMode
27
+ };
@@ -0,0 +1,59 @@
1
+ export interface InlineFieldEditTriggerProps {
2
+ /**
3
+ * Custom label for the edit button.
4
+ * @default "Edit" (translated)
5
+ */
6
+ editLabel?: string;
7
+ }
8
+ /**
9
+ * InlineFieldEditTrigger renders an icon button that switches the InlineField to edit mode.
10
+ * It automatically displays only when the parent InlineField is in read mode.
11
+ * The button uses a pencil icon and handles entering edit mode when clicked.
12
+ * @example Basic usage
13
+ * ```tsx
14
+ * import { useTanstackUnityForm } from '@payfit/unity-components'
15
+ *
16
+ * function Example() {
17
+ * const form = useTanstackUnityForm({ defaultValues: { email: 'john@example.com' } })
18
+ *
19
+ * return (
20
+ * <form.AppForm>
21
+ * <form.AppField name="email">
22
+ * {field => (
23
+ * <field.InlineField>
24
+ * <field.InlineFieldReadView>
25
+ * <div className="flex items-center gap-2">
26
+ * <Text>{form.state.values.email}</Text>
27
+ * <field.InlineFieldEditTrigger />
28
+ * </div>
29
+ * </field.InlineFieldReadView>
30
+ * <field.InlineFieldEditView>
31
+ * <field.TextField label="Email" />
32
+ * </field.InlineFieldEditView>
33
+ * </field.InlineField>
34
+ * )}
35
+ * </form.AppField>
36
+ * </form.AppForm>
37
+ * )
38
+ * }
39
+ * ```
40
+ * @example Custom edit label
41
+ * ```tsx
42
+ * <field.InlineFieldEditTrigger editLabel="Modify" />
43
+ * ```
44
+ * @remarks
45
+ * - Must be used as a child of InlineField
46
+ * - Automatically disabled when InlineField is in edit mode
47
+ * - Uses `aria-controls` and `aria-expanded` for accessibility
48
+ * - Typically placed alongside the read-only value in InlineFieldReadView
49
+ * @see {@link InlineFieldEditTriggerProps} for all available props
50
+ * @see {@link InlineField} for the parent container component
51
+ * @see {@link InlineFieldReadView} for the read mode container
52
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/components/inline-field GitHub}
53
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/docs/forms-reference-inlinefield--docs unity-components.payfit.io}
54
+ */
55
+ declare const InlineFieldEditTrigger: {
56
+ ({ editLabel }: InlineFieldEditTriggerProps): import("react/jsx-runtime").JSX.Element | null;
57
+ displayName: string;
58
+ };
59
+ export { InlineFieldEditTrigger };
@@ -0,0 +1,106 @@
1
+ import { ReactNode } from 'react';
2
+ export interface InlineFieldEditViewProps {
3
+ /**
4
+ * The form field to display in edit mode.
5
+ */
6
+ children?: ReactNode;
7
+ /**
8
+ * Optional callback fired when the cancel button is clicked.
9
+ * This is called before canceling and is useful for analytics or side effects.
10
+ * The form will be reset and edit mode exited automatically.
11
+ */
12
+ onCancel?: () => void;
13
+ /**
14
+ * Optional callback fired when the save button is clicked.
15
+ * This is called before form submission and is useful for analytics or side effects.
16
+ * Note: Form submission is handled via the form's onSubmit configuration.
17
+ */
18
+ onSave?: () => void;
19
+ /**
20
+ * Custom label for the save button.
21
+ * @default "Save" (translated)
22
+ */
23
+ saveLabel?: string;
24
+ /**
25
+ * Custom label for the cancel button.
26
+ * @default "Cancel" (translated)
27
+ */
28
+ cancelLabel?: string;
29
+ /**
30
+ * Helper text to display below the field.
31
+ * Useful for providing additional context or instructions.
32
+ */
33
+ helperText?: ReactNode;
34
+ /**
35
+ * Error message to announce when save or validation fails.
36
+ * If not provided, generic validation errors are announced.
37
+ */
38
+ errorMessage?: string;
39
+ }
40
+ /**
41
+ * InlineFieldEditView displays form fields only when the parent InlineField is in edit mode.
42
+ * Wrap form field components in this component to show them when editing.
43
+ * The component integrates with TanStack Form for validation and state management,
44
+ * automatically handling form submission, cancellation, and validation errors.
45
+ * It includes save and cancel icon buttons, keyboard navigation (Escape to cancel),
46
+ * and accessibility announcements via live regions.
47
+ * @example Basic usage with a text field
48
+ * ```tsx
49
+ * import { useTanstackUnityForm } from '@payfit/unity-components'
50
+ *
51
+ * function Example() {
52
+ * const form = useTanstackUnityForm({
53
+ * defaultValues: { email: 'john@example.com' }
54
+ * })
55
+ *
56
+ * return (
57
+ * <form.AppForm>
58
+ * <form.AppField name="email">
59
+ * {field => (
60
+ * <field.InlineField>
61
+ * <field.InlineFieldReadView>
62
+ * <div className="flex items-center gap-2">
63
+ * <Text>{form.state.values.email}</Text>
64
+ * <field.InlineFieldEditTrigger />
65
+ * </div>
66
+ * </field.InlineFieldReadView>
67
+ * <field.InlineFieldEditView>
68
+ * <field.TextField label="Email" isRequired />
69
+ * </field.InlineFieldEditView>
70
+ * </field.InlineField>
71
+ * )}
72
+ * </form.AppField>
73
+ * </form.AppForm>
74
+ * )
75
+ * }
76
+ * ```
77
+ * @example With custom messages and callbacks
78
+ * ```tsx
79
+ * <field.InlineFieldEditView
80
+ * successMessage="Email updated successfully!"
81
+ * errorMessage="Failed to update email. Please try again."
82
+ * helperText="Enter a valid email address"
83
+ * onSave={() => trackAnalytics('email_save_clicked')}
84
+ * onCancel={() => trackAnalytics('email_edit_cancelled')}
85
+ * >
86
+ * <field.TextField label="Email" isRequired />
87
+ * </field.InlineFieldEditView>
88
+ * ```
89
+ * @remarks
90
+ * - Must be used as a child of InlineField
91
+ * - Automatically exits edit mode on successful form submission
92
+ * - Press Escape to cancel editing and reset form values
93
+ * - Focus is retained within the edit view (FocusScope) while editing
94
+ * - The save button is disabled until the form has changes (isDirty)
95
+ * - Validation errors are announced via screen reader live regions
96
+ * - Content remains in the DOM but is hidden with `hidden`, `aria-hidden`, and `inert` attributes in read mode
97
+ * @see {@link InlineFieldEditViewProps} for all available props
98
+ * @see {@link InlineField} for the parent container component
99
+ * @see {@link InlineFieldReadView} for the corresponding read mode component
100
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/components/inline-field GitHub}
101
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/docs/forms-reference-inlinefield--docs unity-components.payfit.io}
102
+ */
103
+ export declare function InlineFieldEditView({ children, onCancel, onSave, saveLabel, cancelLabel, helperText, errorMessage, }: InlineFieldEditViewProps): import("react/jsx-runtime").JSX.Element;
104
+ export declare namespace InlineFieldEditView {
105
+ var displayName: string;
106
+ }
@@ -0,0 +1,149 @@
1
+ import { jsxs as l, jsx as s } from "react/jsx-runtime";
2
+ import { useRef as S, useState as N, useEffect as m, useCallback as v } from "react";
3
+ import { uyTv as L } from "@payfit/unity-themes";
4
+ import { useStore as P } from "@tanstack/react-form";
5
+ import { useKeyboard as T, FocusScope as R } from "react-aria";
6
+ import { Group as j } from "react-aria-components";
7
+ import { useIntl as K } from "react-intl";
8
+ import { useFormContext as O } from "../../../hooks/tanstack-form-context.js";
9
+ import { TanstackFormFeedbackText as B } from "../../form-field/parts/TanstackFormFeedbackText.js";
10
+ import { TanstackFormHelperText as G } from "../../form-field/parts/TanstackFormHelperText.js";
11
+ import { TanstackFormField as H } from "../../form-field/TanstackFormField.js";
12
+ import { CircularIconButton as h } from "../../icon-button/CircularIconButton.js";
13
+ import { useInlineField as q } from "../InlineField.context.js";
14
+ const z = L({
15
+ slots: {
16
+ base: "uy:flex uy:flex-row uy:gap-100 uy:items-start"
17
+ }
18
+ });
19
+ function J({
20
+ children: x,
21
+ onCancel: f,
22
+ onSave: F,
23
+ saveLabel: C,
24
+ cancelLabel: E,
25
+ helperText: p,
26
+ errorMessage: b
27
+ }) {
28
+ const i = q(), n = K(), o = O(), {
29
+ isDirty: M,
30
+ isSubmitting: t,
31
+ submissionAttempts: u,
32
+ isValid: y,
33
+ isSubmitSuccessful: r
34
+ } = P(o.store, (e) => ({
35
+ isDirty: e.isDirty,
36
+ isSubmitting: e.isSubmitting,
37
+ isValid: e.isValid,
38
+ isSubmitSuccessful: e.isSubmitSuccessful,
39
+ submissionAttempts: e.submissionAttempts
40
+ })), a = S(t), w = S(u), [k, d] = N(""), c = i?.mode === "edit";
41
+ m(() => {
42
+ t && !a.current && d("");
43
+ }, [t]), m(() => {
44
+ a.current && !t && r && i?.exitEditMode();
45
+ }, [t, r, i]), m(() => {
46
+ if (a.current && !t && !r && y) {
47
+ const I = b ?? n.formatMessage({
48
+ id: "unity:component:inline-field:save-error",
49
+ defaultMessage: "An error occurred while saving. Please try again."
50
+ });
51
+ d(I);
52
+ }
53
+ }, [t, r, y, b, n]), m(() => {
54
+ a.current = t, w.current = u;
55
+ }, [t, u]);
56
+ const { base: D } = z(), V = v(
57
+ (e) => {
58
+ e.preventDefault(), e.stopPropagation(), o.handleSubmit();
59
+ },
60
+ [o]
61
+ ), g = v(() => {
62
+ o.reset(), i?.exitEditMode(), d("");
63
+ }, [o, i]), { keyboardProps: A } = T({
64
+ onKeyDown: (e) => {
65
+ e.key === "Escape" && i?.mode === "edit" && (e.preventDefault(), f?.(), g());
66
+ }
67
+ });
68
+ return /* @__PURE__ */ l(
69
+ "div",
70
+ {
71
+ className: D(),
72
+ ref: i?.editViewRef,
73
+ hidden: !c,
74
+ "aria-hidden": !c,
75
+ ...!c && { inert: "" },
76
+ children: [
77
+ /* @__PURE__ */ s(R, { contain: !0, restoreFocus: !0, children: /* @__PURE__ */ s(
78
+ "form",
79
+ {
80
+ ...A,
81
+ className: "uy:flex uy:flex-1 uy:min-w-0",
82
+ onSubmit: V,
83
+ id: i?.editViewId,
84
+ children: /* @__PURE__ */ l(H, { children: [
85
+ p && /* @__PURE__ */ s(G, { children: p }),
86
+ /* @__PURE__ */ l("div", { className: "uy:flex", children: [
87
+ x,
88
+ /* @__PURE__ */ l(
89
+ j,
90
+ {
91
+ className: "uy:flex uy:gap-50 uy:items-center uy:ml-100",
92
+ "aria-busy": i?.isLoading,
93
+ children: [
94
+ /* @__PURE__ */ s(
95
+ h,
96
+ {
97
+ asElement: "button",
98
+ icon: "CloseOutlined",
99
+ onPress: () => {
100
+ f?.(), g();
101
+ },
102
+ isDisabled: i?.isLoading,
103
+ title: E ?? n.formatMessage({
104
+ id: "unity:component:inline-field:cancel",
105
+ defaultMessage: "Cancel"
106
+ })
107
+ }
108
+ ),
109
+ /* @__PURE__ */ s(
110
+ h,
111
+ {
112
+ asElement: "button",
113
+ icon: "CheckOutlined",
114
+ type: "submit",
115
+ isLoading: i?.isLoading || t,
116
+ isDisabled: !M || i?.isLoading || t,
117
+ title: C ?? n.formatMessage({
118
+ id: "unity:component:inline-field:save",
119
+ defaultMessage: "Save"
120
+ }),
121
+ onPress: F
122
+ }
123
+ )
124
+ ]
125
+ }
126
+ )
127
+ ] }),
128
+ /* @__PURE__ */ s(B, {})
129
+ ] })
130
+ }
131
+ ) }),
132
+ /* @__PURE__ */ s(
133
+ "div",
134
+ {
135
+ role: "alert",
136
+ "aria-live": "assertive",
137
+ "aria-atomic": "true",
138
+ className: "uy:sr-only",
139
+ children: k
140
+ }
141
+ )
142
+ ]
143
+ }
144
+ );
145
+ }
146
+ J.displayName = "InlineFieldEditView";
147
+ export {
148
+ J as InlineFieldEditView
149
+ };
@@ -0,0 +1,75 @@
1
+ import { ReactNode } from 'react';
2
+ export interface InlineFieldReadViewProps {
3
+ /**
4
+ * Content to display in read mode.
5
+ * Typically includes the read-only value and an InlineFieldEditTrigger.
6
+ */
7
+ children: ReactNode;
8
+ /**
9
+ * Success message to announce when save succeeds.
10
+ * If not provided, no success announcement is made.
11
+ */
12
+ successMessage?: string;
13
+ }
14
+ /**
15
+ * InlineFieldReadView displays content only when the parent InlineField is in read mode.
16
+ * Wrap read-only content and the edit trigger button in this component.
17
+ * The component automatically hides its content when the parent switches to edit mode,
18
+ * using semantic HTML attributes for accessibility.
19
+ * @example Basic usage with read-only value
20
+ * ```tsx
21
+ * import { useTanstackUnityForm } from '@payfit/unity-components'
22
+ *
23
+ * function Example() {
24
+ * const form = useTanstackUnityForm({
25
+ * defaultValues: { email: 'john@example.com' }
26
+ * })
27
+ *
28
+ * return (
29
+ * <form.AppForm>
30
+ * <form.AppField name="email">
31
+ * {field => (
32
+ * <field.InlineField>
33
+ * <field.InlineFieldReadView>
34
+ * <div className="flex items-center gap-2">
35
+ * <Text>{form.state.values.email}</Text>
36
+ * <field.InlineFieldEditTrigger />
37
+ * </div>
38
+ * </field.InlineFieldReadView>
39
+ * <field.InlineFieldEditView>
40
+ * <field.TextField label="Email" />
41
+ * </field.InlineFieldEditView>
42
+ * </field.InlineField>
43
+ * )}
44
+ * </form.AppField>
45
+ * </form.AppForm>
46
+ * )
47
+ * }
48
+ * ```
49
+ * @example With formatted display
50
+ * ```tsx
51
+ * <field.InlineFieldReadView>
52
+ * <div className="flex items-center justify-between">
53
+ * <div>
54
+ * <Label>Email</Label>
55
+ * <Text>{form.state.values.email}</Text>
56
+ * </div>
57
+ * <field.InlineFieldEditTrigger />
58
+ * </div>
59
+ * </field.InlineFieldReadView>
60
+ * ```
61
+ * @remarks
62
+ * - Must be used as a child of InlineField
63
+ * - Content remains in the DOM but is hidden with `hidden`, `aria-hidden`, and `inert` attributes in edit mode
64
+ * - Use this component to wrap both the read-only value and the InlineFieldEditTrigger
65
+ * @see {@link InlineFieldReadViewProps} for all available props
66
+ * @see {@link InlineField} for the parent container component
67
+ * @see {@link InlineFieldEditView} for the corresponding edit mode component
68
+ * @see {@link InlineFieldEditTrigger} for the button to enter edit mode
69
+ * @see Source code in {@link https://github.com/PayFit/hr-apps/tree/master/libs/shared/unity/components/src/components/inline-field GitHub}
70
+ * @see Developer docs in {@link https://unity-components.payfit.io/?path=/docs/forms-reference-inlinefield--docs unity-components.payfit.io}
71
+ */
72
+ export declare function InlineFieldReadView({ children, successMessage, }: InlineFieldReadViewProps): import("react/jsx-runtime").JSX.Element;
73
+ export declare namespace InlineFieldReadView {
74
+ var displayName: string;
75
+ }
@@ -0,0 +1,58 @@
1
+ import { jsxs as a, jsx as p } from "react/jsx-runtime";
2
+ import { useState as S, useRef as c, useEffect as r } from "react";
3
+ import { useStore as b } from "@tanstack/react-form";
4
+ import { useFormContext as R } from "../../../hooks/tanstack-form-context.js";
5
+ import { useInlineField as A } from "../InlineField.context.js";
6
+ const I = 5e3;
7
+ function x({
8
+ children: d,
9
+ successMessage: i
10
+ }) {
11
+ const n = A(), [l, s] = S(""), f = R(), { isSubmitting: e, submissionAttempts: E, isSubmitSuccessful: m } = b(
12
+ f.store,
13
+ (t) => ({
14
+ isSubmitting: t.isSubmitting,
15
+ isSubmitSuccessful: t.isSubmitSuccessful,
16
+ submissionAttempts: t.submissionAttempts
17
+ })
18
+ ), u = c(e), o = n?.mode === "read";
19
+ return r(() => {
20
+ u.current && !e && m && i && s(i);
21
+ }, [e, m, i, n]), r(() => {
22
+ if (i && !n?.isLoading && o && m) {
23
+ s(i);
24
+ const t = setTimeout(() => {
25
+ s("");
26
+ }, I);
27
+ return () => {
28
+ clearTimeout(t);
29
+ };
30
+ }
31
+ }, [i, n, o, m]), r(() => {
32
+ e && !u.current && s("");
33
+ }, [e]), /* @__PURE__ */ a(
34
+ "div",
35
+ {
36
+ hidden: !o,
37
+ "aria-hidden": !o,
38
+ ...!o && { inert: "" },
39
+ children: [
40
+ d,
41
+ /* @__PURE__ */ p(
42
+ "div",
43
+ {
44
+ role: "status",
45
+ "aria-live": "polite",
46
+ "aria-atomic": "true",
47
+ className: "uy:sr-only",
48
+ children: l
49
+ }
50
+ )
51
+ ]
52
+ }
53
+ );
54
+ }
55
+ x.displayName = "InlineFieldReadView";
56
+ export {
57
+ x as InlineFieldReadView
58
+ };
@@ -57,6 +57,12 @@ export declare const useTanstackUnityForm: <TFormData, TOnMount extends import('
57
57
  readonly TextField: import('react').ForwardRefExoticComponent<import('../components/text-field/TanstackTextField.js').TextFieldProps & import('react').RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
58
58
  readonly ToggleSwitchField: import('react').ForwardRefExoticComponent<Omit<import('../components/toggle-switch-field/TanstackToggleSwitchField.js').TanstackToggleSwitchFieldProps, "ref"> & import('react').RefAttributes<HTMLLabelElement>>;
59
59
  readonly ToggleSwitchGroupField: import('react').ForwardRefExoticComponent<import('../components/toggle-switch-group-field/TanstackToggleSwitchGroupField.js').TanstackToggleSwitchGroupFieldProps & import('react').RefAttributes<HTMLFieldSetElement>>;
60
+ readonly InlineField: {
61
+ ({ children, mode: controlledMode, defaultMode, onModeChange, isLoading, shouldModeChange, }: import('../components/inline-field/InlineField.js').InlineFieldProps): import("react/jsx-runtime").JSX.Element;
62
+ displayName: string;
63
+ };
64
+ readonly InlineFieldReadView: typeof import('../components/inline-field/parts/InlineFieldReadView.js').InlineFieldReadView;
65
+ readonly InlineFieldEditView: typeof import('../components/inline-field/parts/InlineFieldEditView.js').InlineFieldEditView;
60
66
  }, {
61
67
  readonly Form: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & import('react').RefAttributes<HTMLFormElement>>;
62
68
  readonly InlineFieldGroup: import('react').ForwardRefExoticComponent<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupProps & import('react').RefAttributes<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupHandle>>;
@@ -122,6 +128,12 @@ export declare const withForm: <TFormData, TOnMount extends import('@tanstack/fo
122
128
  readonly TextField: import('react').ForwardRefExoticComponent<import('../components/text-field/TanstackTextField.js').TextFieldProps & import('react').RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
123
129
  readonly ToggleSwitchField: import('react').ForwardRefExoticComponent<Omit<import('../components/toggle-switch-field/TanstackToggleSwitchField.js').TanstackToggleSwitchFieldProps, "ref"> & import('react').RefAttributes<HTMLLabelElement>>;
124
130
  readonly ToggleSwitchGroupField: import('react').ForwardRefExoticComponent<import('../components/toggle-switch-group-field/TanstackToggleSwitchGroupField.js').TanstackToggleSwitchGroupFieldProps & import('react').RefAttributes<HTMLFieldSetElement>>;
131
+ readonly InlineField: {
132
+ ({ children, mode: controlledMode, defaultMode, onModeChange, isLoading, shouldModeChange, }: import('../components/inline-field/InlineField.js').InlineFieldProps): import("react/jsx-runtime").JSX.Element;
133
+ displayName: string;
134
+ };
135
+ readonly InlineFieldReadView: typeof import('../components/inline-field/parts/InlineFieldReadView.js').InlineFieldReadView;
136
+ readonly InlineFieldEditView: typeof import('../components/inline-field/parts/InlineFieldEditView.js').InlineFieldEditView;
125
137
  }, {
126
138
  readonly Form: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & import('react').RefAttributes<HTMLFormElement>>;
127
139
  readonly InlineFieldGroup: import('react').ForwardRefExoticComponent<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupProps & import('react').RefAttributes<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupHandle>>;
@@ -187,6 +199,12 @@ export declare const withForm: <TFormData, TOnMount extends import('@tanstack/fo
187
199
  readonly TextField: import('react').ForwardRefExoticComponent<import('../components/text-field/TanstackTextField.js').TextFieldProps & import('react').RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
188
200
  readonly ToggleSwitchField: import('react').ForwardRefExoticComponent<Omit<import('../components/toggle-switch-field/TanstackToggleSwitchField.js').TanstackToggleSwitchFieldProps, "ref"> & import('react').RefAttributes<HTMLLabelElement>>;
189
201
  readonly ToggleSwitchGroupField: import('react').ForwardRefExoticComponent<import('../components/toggle-switch-group-field/TanstackToggleSwitchGroupField.js').TanstackToggleSwitchGroupFieldProps & import('react').RefAttributes<HTMLFieldSetElement>>;
202
+ readonly InlineField: {
203
+ ({ children, mode: controlledMode, defaultMode, onModeChange, isLoading, shouldModeChange, }: import('../components/inline-field/InlineField.js').InlineFieldProps): import("react/jsx-runtime").JSX.Element;
204
+ displayName: string;
205
+ };
206
+ readonly InlineFieldReadView: typeof import('../components/inline-field/parts/InlineFieldReadView.js').InlineFieldReadView;
207
+ readonly InlineFieldEditView: typeof import('../components/inline-field/parts/InlineFieldEditView.js').InlineFieldEditView;
190
208
  }, {
191
209
  readonly Form: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & import('react').RefAttributes<HTMLFormElement>>;
192
210
  readonly InlineFieldGroup: import('react').ForwardRefExoticComponent<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupProps & import('react').RefAttributes<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupHandle>>;
@@ -253,6 +271,12 @@ export declare const withFieldGroup: <TFieldGroupData, TSubmitMeta, TRenderProps
253
271
  readonly TextField: import('react').ForwardRefExoticComponent<import('../components/text-field/TanstackTextField.js').TextFieldProps & import('react').RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
254
272
  readonly ToggleSwitchField: import('react').ForwardRefExoticComponent<Omit<import('../components/toggle-switch-field/TanstackToggleSwitchField.js').TanstackToggleSwitchFieldProps, "ref"> & import('react').RefAttributes<HTMLLabelElement>>;
255
273
  readonly ToggleSwitchGroupField: import('react').ForwardRefExoticComponent<import('../components/toggle-switch-group-field/TanstackToggleSwitchGroupField.js').TanstackToggleSwitchGroupFieldProps & import('react').RefAttributes<HTMLFieldSetElement>>;
274
+ readonly InlineField: {
275
+ ({ children, mode: controlledMode, defaultMode, onModeChange, isLoading, shouldModeChange, }: import('../components/inline-field/InlineField.js').InlineFieldProps): import("react/jsx-runtime").JSX.Element;
276
+ displayName: string;
277
+ };
278
+ readonly InlineFieldReadView: typeof import('../components/inline-field/parts/InlineFieldReadView.js').InlineFieldReadView;
279
+ readonly InlineFieldEditView: typeof import('../components/inline-field/parts/InlineFieldEditView.js').InlineFieldEditView;
256
280
  }, {
257
281
  readonly Form: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & import('react').RefAttributes<HTMLFormElement>>;
258
282
  readonly InlineFieldGroup: import('react').ForwardRefExoticComponent<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupProps & import('react').RefAttributes<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupHandle>>;
@@ -318,6 +342,12 @@ export declare const withFieldGroup: <TFieldGroupData, TSubmitMeta, TRenderProps
318
342
  readonly TextField: import('react').ForwardRefExoticComponent<import('../components/text-field/TanstackTextField.js').TextFieldProps & import('react').RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
319
343
  readonly ToggleSwitchField: import('react').ForwardRefExoticComponent<Omit<import('../components/toggle-switch-field/TanstackToggleSwitchField.js').TanstackToggleSwitchFieldProps, "ref"> & import('react').RefAttributes<HTMLLabelElement>>;
320
344
  readonly ToggleSwitchGroupField: import('react').ForwardRefExoticComponent<import('../components/toggle-switch-group-field/TanstackToggleSwitchGroupField.js').TanstackToggleSwitchGroupFieldProps & import('react').RefAttributes<HTMLFieldSetElement>>;
345
+ readonly InlineField: {
346
+ ({ children, mode: controlledMode, defaultMode, onModeChange, isLoading, shouldModeChange, }: import('../components/inline-field/InlineField.js').InlineFieldProps): import("react/jsx-runtime").JSX.Element;
347
+ displayName: string;
348
+ };
349
+ readonly InlineFieldReadView: typeof import('../components/inline-field/parts/InlineFieldReadView.js').InlineFieldReadView;
350
+ readonly InlineFieldEditView: typeof import('../components/inline-field/parts/InlineFieldEditView.js').InlineFieldEditView;
321
351
  }, {
322
352
  readonly Form: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & import('react').RefAttributes<HTMLFormElement>>;
323
353
  readonly InlineFieldGroup: import('react').ForwardRefExoticComponent<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupProps & import('react').RefAttributes<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupHandle>>;
@@ -382,6 +412,12 @@ export declare const withFieldGroup: <TFieldGroupData, TSubmitMeta, TRenderProps
382
412
  readonly TextField: import('react').ForwardRefExoticComponent<import('../components/text-field/TanstackTextField.js').TextFieldProps & import('react').RefAttributes<HTMLInputElement | HTMLTextAreaElement>>;
383
413
  readonly ToggleSwitchField: import('react').ForwardRefExoticComponent<Omit<import('../components/toggle-switch-field/TanstackToggleSwitchField.js').TanstackToggleSwitchFieldProps, "ref"> & import('react').RefAttributes<HTMLLabelElement>>;
384
414
  readonly ToggleSwitchGroupField: import('react').ForwardRefExoticComponent<import('../components/toggle-switch-group-field/TanstackToggleSwitchGroupField.js').TanstackToggleSwitchGroupFieldProps & import('react').RefAttributes<HTMLFieldSetElement>>;
415
+ readonly InlineField: {
416
+ ({ children, mode: controlledMode, defaultMode, onModeChange, isLoading, shouldModeChange, }: import('../components/inline-field/InlineField.js').InlineFieldProps): import("react/jsx-runtime").JSX.Element;
417
+ displayName: string;
418
+ };
419
+ readonly InlineFieldReadView: typeof import('../components/inline-field/parts/InlineFieldReadView.js').InlineFieldReadView;
420
+ readonly InlineFieldEditView: typeof import('../components/inline-field/parts/InlineFieldEditView.js').InlineFieldEditView;
385
421
  }, {
386
422
  readonly Form: import('react').ForwardRefExoticComponent<Omit<import('react').DetailedHTMLProps<import('react').FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, "ref"> & import('react').RefAttributes<HTMLFormElement>>;
387
423
  readonly InlineFieldGroup: import('react').ForwardRefExoticComponent<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupProps & import('react').RefAttributes<import('../components/inline-field-group/InlineFieldGroup.js').InlineFieldGroupHandle>>;
@@ -1,6 +1,6 @@
1
1
  import { lazy as e } from "react";
2
- import { createFormHook as o } from "@tanstack/react-form";
3
- import { TanstackForm as n } from "../components/form/TanstackForm.js";
2
+ import { createFormHook as n } from "@tanstack/react-form";
3
+ import { TanstackForm as o } from "../components/form/TanstackForm.js";
4
4
  import { formContext as l, fieldContext as c } from "./tanstack-form-context.js";
5
5
  const i = e(
6
6
  () => import("../components/checkbox-field/TanstackCheckboxField.js").then((t) => ({
@@ -12,11 +12,11 @@ const i = e(
12
12
  default: t.TanstackFormFeedbackText
13
13
  })
14
14
  )
15
- ), u = e(
15
+ ), d = e(
16
16
  () => import("../components/form-field/parts/TanstackFormHelperText.js").then((t) => ({
17
17
  default: t.TanstackFormHelperText
18
18
  }))
19
- ), d = e(
19
+ ), u = e(
20
20
  () => import("../components/form-field/parts/TanstackFormLabel.js").then((t) => ({
21
21
  default: t.TanstackFormLabel
22
22
  }))
@@ -38,11 +38,11 @@ const i = e(
38
38
  () => import("../components/checkbox/TanstackCheckbox.js").then((t) => ({
39
39
  default: t.TanstackCheckbox
40
40
  }))
41
- ), m = e(
41
+ ), F = e(
42
42
  () => import("../components/date-picker/TanstackDatePicker.js").then((t) => ({
43
43
  default: t.TanstackDatePicker
44
44
  }))
45
- ), F = e(
45
+ ), m = e(
46
46
  () => import("../components/multi-select/TanstackMultiSelect.js").then((t) => ({
47
47
  default: t.TanstackMultiSelect
48
48
  }))
@@ -82,11 +82,11 @@ const i = e(
82
82
  () => import("../components/select/TanstackSelect.js").then((t) => ({
83
83
  default: t.TanstackSelect
84
84
  }))
85
- ), g = e(
85
+ ), w = e(
86
86
  () => import("../components/text-area/TanstackTextArea.js").then((t) => ({
87
87
  default: t.TanstackTextArea
88
88
  }))
89
- ), w = e(
89
+ ), g = e(
90
90
  () => import("../components/input/TanstackInput.js").then((t) => ({
91
91
  default: t.TanstackInput
92
92
  }))
@@ -112,37 +112,37 @@ const i = e(
112
112
  default: t.TanstackDatePickerField
113
113
  })
114
114
  )
115
- ), H = e(
115
+ ), V = e(
116
116
  () => import("../components/multi-select-field/TanstackMultiSelectField.js").then(
117
117
  (t) => ({
118
118
  default: t.TanstackMultiSelectField
119
119
  })
120
120
  )
121
- ), D = e(
121
+ ), H = e(
122
122
  () => import("../components/number-field/TanstackNumberField.js").then((t) => ({
123
123
  default: t.TanstackNumberField
124
124
  }))
125
- ), L = e(
125
+ ), D = e(
126
126
  () => import("../components/radio-button-group-field/TanstackRadioButtonGroupField.js").then((t) => ({
127
127
  default: t.TanstackRadioButtonGroupField
128
128
  }))
129
- ), M = e(
129
+ ), L = e(
130
130
  () => import("../components/select-field/TanstackSelectField.js").then((t) => ({
131
131
  default: t.TanstackSelectField
132
132
  }))
133
- ), A = e(
133
+ ), M = e(
134
134
  () => import("../components/selectable-button-group-field/TanstackSelectableButtonGroupField.js").then((t) => ({
135
135
  default: t.TanstackSelectableButtonGroupField
136
136
  }))
137
- ), V = e(
137
+ ), A = e(
138
138
  () => import("../components/selectable-card-checkbox-group-field/TanstackSelectableCardCheckboxGroupField.js").then((t) => ({
139
139
  default: t.TanstackSelectableCardCheckboxGroupField
140
140
  }))
141
- ), y = e(
141
+ ), E = e(
142
142
  () => import("../components/selectable-card-radio-group-field/TanstackSelectableCardRadioGroupField.js").then((t) => ({
143
143
  default: t.TanstackSelectableCardRadioGroupField
144
144
  }))
145
- ), E = e(
145
+ ), y = e(
146
146
  () => import("../components/text-field/TanstackTextField.js").then((t) => ({
147
147
  default: t.TanstackTextField
148
148
  }))
@@ -174,19 +174,31 @@ const i = e(
174
174
  () => import("../components/inline-field-group/parts/InlineFieldGroupEditView.js").then((t) => ({
175
175
  default: t.InlineFieldGroupEditView
176
176
  }))
177
- ), a = o({
177
+ ), K = e(
178
+ () => import("../components/inline-field/parts/InlineFieldEditView.js").then((t) => ({
179
+ default: t.InlineFieldEditView
180
+ }))
181
+ ), O = e(
182
+ () => import("../components/inline-field/parts/InlineFieldReadView.js").then((t) => ({
183
+ default: t.InlineFieldReadView
184
+ }))
185
+ ), Q = e(
186
+ () => import("../components/inline-field/InlineField.js").then((t) => ({
187
+ default: t.InlineField
188
+ }))
189
+ ), a = n({
178
190
  fieldComponents: {
179
191
  // Base components for field building
180
192
  FieldFeedbackText: r,
181
- FieldHelperText: u,
182
- FieldLabel: d,
193
+ FieldHelperText: d,
194
+ FieldLabel: u,
183
195
  FieldRawContextualLink: p,
184
196
  Field: s,
185
197
  // bound input components
186
198
  CheckboxGroupInput: k,
187
199
  CheckboxInput: T,
188
- DatePickerInput: m,
189
- MultiSelectInput: F,
200
+ DatePickerInput: F,
201
+ MultiSelectInput: m,
190
202
  PhoneNumberInput: h,
191
203
  NumberInput: f,
192
204
  RadioButtonInput: G,
@@ -194,28 +206,32 @@ const i = e(
194
206
  SelectableCardCheckboxGroupInput: C,
195
207
  SelectableCardRadioGroupInput: x,
196
208
  SelectInput: I,
197
- TextAreaInput: g,
198
- TextInput: w,
209
+ TextAreaInput: w,
210
+ TextInput: g,
199
211
  ToggleSwitchGroupInput: R,
200
212
  ToggleSwitchInput: B,
201
213
  // Field organisms
202
214
  CheckboxField: i,
203
215
  CheckboxGroupField: N,
204
216
  DatePickerField: P,
205
- MultiSelectField: H,
206
- NumberField: D,
217
+ MultiSelectField: V,
218
+ NumberField: H,
207
219
  PhoneNumberField: b,
208
- RadioButtonGroupField: L,
209
- SelectableButtonGroupField: A,
210
- SelectableCardCheckboxGroupField: V,
211
- SelectableCardRadioGroupField: y,
212
- SelectField: M,
213
- TextField: E,
220
+ RadioButtonGroupField: D,
221
+ SelectableButtonGroupField: M,
222
+ SelectableCardCheckboxGroupField: A,
223
+ SelectableCardRadioGroupField: E,
224
+ SelectField: L,
225
+ TextField: y,
214
226
  ToggleSwitchField: z,
215
- ToggleSwitchGroupField: U
227
+ ToggleSwitchGroupField: U,
228
+ // Inline Edition components
229
+ InlineField: Q,
230
+ InlineFieldReadView: O,
231
+ InlineFieldEditView: K
216
232
  },
217
233
  formComponents: {
218
- Form: n,
234
+ Form: o,
219
235
  // Inline Edition components
220
236
  InlineFieldGroup: j,
221
237
  InlineFieldGroupHeader: q,
@@ -224,9 +240,9 @@ const i = e(
224
240
  },
225
241
  fieldContext: c,
226
242
  formContext: l
227
- }), X = a.useAppForm, Y = a.withForm, Z = a.withFieldGroup;
243
+ }), _ = a.useAppForm, $ = a.withForm, tt = a.withFieldGroup;
228
244
  export {
229
- X as useTanstackUnityForm,
230
- Z as withFieldGroup,
231
- Y as withForm
245
+ _ as useTanstackUnityForm,
246
+ tt as withFieldGroup,
247
+ $ as withForm
232
248
  };
package/i18n/en-GB.json CHANGED
@@ -63,6 +63,11 @@
63
63
  "unity:component:inline-field-group:loading": "Loading...",
64
64
  "unity:component:inline-field-group:validation-error": "Please fix the errors before saving.",
65
65
  "unity:component:inline-field-group:save-error": "An error occurred while saving. Please try again.",
66
+ "unity:component:inline-field:cancel": "Cancel",
67
+ "unity:component:inline-field:save": "Save",
68
+ "unity:component:inline-field:validation-error": "Please fix the errors before saving.",
69
+ "unity:component:inline-field:save-error": "An error occurred while saving. Please try again.",
70
+ "unity:component:inline-field:edit": "Edit",
66
71
  "unity:component:label:required": "required",
67
72
  "unity:component:label:optional": "(optional)",
68
73
  "unity:component:pagination:label": "Pagination",
package/i18n/es-ES.json CHANGED
@@ -63,6 +63,11 @@
63
63
  "unity:component:inline-field-group:loading": "Guardando...",
64
64
  "unity:component:inline-field-group:validation-error": "Por favor, corrige los errores antes de guardar.",
65
65
  "unity:component:inline-field-group:save-error": "Se produjo un error al guardar. Por favor, inténtalo de nuevo.",
66
+ "unity:component:inline-field:cancel": "Cancelar",
67
+ "unity:component:inline-field:save": "Guardar",
68
+ "unity:component:inline-field:validation-error": "Por favor, corrige los errores antes de guardar.",
69
+ "unity:component:inline-field:save-error": "Se produjo un error al guardar. Por favor, inténtalo de nuevo.",
70
+ "unity:component:inline-field:edit": "Editar",
66
71
  "unity:component:label:required": "obligatorio",
67
72
  "unity:component:label:optional": "(opcional)",
68
73
  "unity:component:pagination:label": "Paginación",
package/i18n/fr-FR.json CHANGED
@@ -63,6 +63,11 @@
63
63
  "unity:component:inline-field-group:loading": "En cours de sauvegarde...",
64
64
  "unity:component:inline-field-group:validation-error": "Veuillez corriger les erreurs avant d'enregistrer.",
65
65
  "unity:component:inline-field-group:save-error": "Une erreur s'est produite lors de l'enregistrement. Veuillez réessayer.",
66
+ "unity:component:inline-field:cancel": "Annuler",
67
+ "unity:component:inline-field:save": "Enregistrer",
68
+ "unity:component:inline-field:validation-error": "Veuillez corriger les erreurs avant d'enregistrer.",
69
+ "unity:component:inline-field:save-error": "Une erreur s'est produite lors de l'enregistrement. Veuillez réessayer.",
70
+ "unity:component:inline-field:edit": "Modifier",
66
71
  "unity:component:label:required": "obligatoire",
67
72
  "unity:component:label:optional": "(optionnel)",
68
73
  "unity:component:pagination:label": "Pagination",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payfit/unity-components",
3
- "version": "2.2.8",
3
+ "version": "2.3.1",
4
4
  "module": "./dist/esm/index.js",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -42,13 +42,13 @@
42
42
  "@hookform/devtools": "4.4.0",
43
43
  "@hookform/resolvers": "5.2.1",
44
44
  "@internationalized/date": "3.10.0",
45
- "@payfit/unity-illustrations": "2.2.8",
45
+ "@payfit/unity-illustrations": "2.3.1",
46
46
  "@radix-ui/react-avatar": "1.1.11",
47
47
  "@radix-ui/react-slot": "1.2.4",
48
48
  "@react-aria/interactions": "3.25.6",
49
49
  "@react-aria/utils": "3.31.0",
50
50
  "@react-types/shared": "3.26.0",
51
- "@standard-schema/spec": "1.0.0",
51
+ "@standard-schema/spec": "1.1.0",
52
52
  "@tanstack/react-form": "1.28.0",
53
53
  "@tanstack/react-virtual": "3.13.12",
54
54
  "@use-gesture/react": "10.3.1",
@@ -70,8 +70,8 @@
70
70
  },
71
71
  "peerDependencies": {
72
72
  "@hookform/devtools": "^4",
73
- "@payfit/unity-icons": "2.2.8",
74
- "@payfit/unity-themes": "2.2.8",
73
+ "@payfit/unity-icons": "2.3.1",
74
+ "@payfit/unity-themes": "2.3.1",
75
75
  "@storybook/react-vite": "^10.2.2",
76
76
  "@tanstack/react-query": "^5",
77
77
  "@tanstack/react-router": "^1.131",
@@ -90,9 +90,9 @@
90
90
  "@payfit/hr-apps-tsconfigs": "0.0.0-use.local",
91
91
  "@payfit/storybook-addon-console-errors": "0.0.0-use.local",
92
92
  "@payfit/storybook-config": "0.0.0-use.local",
93
- "@payfit/unity-icons": "2.2.8",
94
- "@payfit/unity-illustrations": "2.2.8",
95
- "@payfit/unity-themes": "2.2.8",
93
+ "@payfit/unity-icons": "2.3.1",
94
+ "@payfit/unity-illustrations": "2.3.1",
95
+ "@payfit/unity-themes": "2.3.1",
96
96
  "@payfit/vite-configs": "0.0.0-use.local",
97
97
  "@storybook/addon-a11y": "10.2.2",
98
98
  "@storybook/addon-docs": "10.2.2",