@gusto/embedded-react-sdk 0.49.0 → 0.50.0

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.
Files changed (154) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/components/Base/createCompoundContext.d.ts +1 -1
  3. package/dist/components/Base/createCompoundContext.js.map +1 -1
  4. package/dist/components/Common/UI/Breadcrumbs/Breadcrumbs.js +1 -1
  5. package/dist/components/Common/UI/CalendarPreview/CalendarLegend.d.ts +1 -1
  6. package/dist/components/Common/UI/CalendarPreview/CalendarLegend.js.map +1 -1
  7. package/dist/components/Common/UI/FileInput/FileInput.js +1 -1
  8. package/dist/components/Common/UI/ProgressBar/ProgressBar.js +4 -4
  9. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js +5 -3
  10. package/dist/components/Company/AssignSignatory/CreateSignatory/useCreateSignatory.js.map +1 -1
  11. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js +5 -3
  12. package/dist/components/Company/AssignSignatory/InviteSignatory/useInviteSignatory.js.map +1 -1
  13. package/dist/components/Company/AssignSignatory/useAssignSignatory.js +7 -5
  14. package/dist/components/Company/AssignSignatory/useAssignSignatory.js.map +1 -1
  15. package/dist/components/Company/BankAccount/BankAccountForm/context.js +5 -3
  16. package/dist/components/Company/BankAccount/BankAccountForm/context.js.map +1 -1
  17. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js +5 -3
  18. package/dist/components/Company/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  19. package/dist/components/Company/DocumentSigner/shared/useSignCompanyForm/signCompanyFormSchema.d.ts +1 -0
  20. package/dist/components/Company/DocumentSigner/shared/useSignCompanyForm/signCompanyFormSchema.js.map +1 -1
  21. package/dist/components/Company/FederalTaxes/useFederalTaxes.js +10 -8
  22. package/dist/components/Company/FederalTaxes/useFederalTaxes.js.map +1 -1
  23. package/dist/components/Company/Industry/Context.js +8 -6
  24. package/dist/components/Company/Industry/Context.js.map +1 -1
  25. package/dist/components/Company/Locations/LocationForm/useLocationForm.js +5 -3
  26. package/dist/components/Company/Locations/LocationForm/useLocationForm.js.map +1 -1
  27. package/dist/components/Company/Locations/LocationsList/useLocationsList.js +5 -3
  28. package/dist/components/Company/Locations/LocationsList/useLocationsList.js.map +1 -1
  29. package/dist/components/Company/OnboardingFlow/OnboardingFlow.d.ts +1 -1
  30. package/dist/components/Company/OnboardingFlow/OnboardingFlow.js.map +1 -1
  31. package/dist/components/Company/OnboardingOverview/context.js +5 -3
  32. package/dist/components/Company/OnboardingOverview/context.js.map +1 -1
  33. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/payScheduleSchema.d.ts +1 -0
  34. package/dist/components/Company/PaySchedule/shared/usePayScheduleForm/payScheduleSchema.js.map +1 -1
  35. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js +5 -3
  36. package/dist/components/Company/StateTaxes/StateTaxesForm/context.js.map +1 -1
  37. package/dist/components/Company/StateTaxes/StateTaxesList/context.js +5 -3
  38. package/dist/components/Company/StateTaxes/StateTaxesList/context.js.map +1 -1
  39. package/dist/components/Contractor/Address/shared/useContractorAddressForm/contractorAddressSchema.d.ts +1 -0
  40. package/dist/components/Contractor/Address/shared/useContractorAddressForm/contractorAddressSchema.js.map +1 -1
  41. package/dist/components/Contractor/Address/shared/useContractorAddressForm/useContractorAddressForm.d.ts +38 -0
  42. package/dist/components/Contractor/Address/shared/useContractorAddressForm/useContractorAddressForm.js.map +1 -1
  43. package/dist/components/Contractor/Documents/DocumentsList/useContractorDocumentsList/useContractorDocumentsList.d.ts +1 -0
  44. package/dist/components/Contractor/Documents/DocumentsList/useContractorDocumentsList/useContractorDocumentsList.js.map +1 -1
  45. package/dist/components/Contractor/OnboardingFlow/OnboardingFlow.d.ts +3 -3
  46. package/dist/components/Contractor/OnboardingFlow/OnboardingFlow.js.map +1 -1
  47. package/dist/components/Contractor/PaymentMethod/PaymentMethod.d.ts +5 -5
  48. package/dist/components/Contractor/PaymentMethod/PaymentMethod.js +105 -108
  49. package/dist/components/Contractor/PaymentMethod/PaymentMethod.js.map +1 -1
  50. package/dist/components/Contractor/PaymentMethod/PaymentMethod.module.scss.js +8 -0
  51. package/dist/components/Contractor/PaymentMethod/PaymentMethod.module.scss.js.map +1 -0
  52. package/dist/components/Contractor/PaymentMethod/shared/index.d.ts +2 -0
  53. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/fields.d.ts +93 -0
  54. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/fields.js +22 -0
  55. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/fields.js.map +1 -0
  56. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/index.d.ts +5 -0
  57. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/useContractorBankAccountForm.d.ts +127 -0
  58. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/useContractorBankAccountForm.js +109 -0
  59. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/useContractorBankAccountForm.js.map +1 -0
  60. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/useContractorBankAccountFormSchema.d.ts +83 -0
  61. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/useContractorBankAccountFormSchema.js +42 -0
  62. package/dist/components/Contractor/PaymentMethod/shared/useContractorBankAccountForm/useContractorBankAccountFormSchema.js.map +1 -0
  63. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/contractorPaymentMethodSchema.d.ts +58 -0
  64. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/contractorPaymentMethodSchema.js +21 -0
  65. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/contractorPaymentMethodSchema.js.map +1 -0
  66. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/fields.d.ts +20 -0
  67. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/fields.js +9 -0
  68. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/fields.js.map +1 -0
  69. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/index.d.ts +5 -0
  70. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/useContractorPaymentMethodForm.d.ts +117 -0
  71. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/useContractorPaymentMethodForm.js +91 -0
  72. package/dist/components/Contractor/PaymentMethod/shared/useContractorPaymentMethodForm/useContractorPaymentMethodForm.js.map +1 -0
  73. package/dist/components/Contractor/PaymentMethod/types.d.ts +0 -5
  74. package/dist/components/Contractor/Payments/PaymentFlow/PaymentFlow.d.ts +2 -2
  75. package/dist/components/Contractor/Payments/PaymentFlow/PaymentFlow.js.map +1 -1
  76. package/dist/components/Contractor/Profile/shared/useContractorDetailsForm/contractorDetailsSchema.d.ts +1 -0
  77. package/dist/components/Contractor/Profile/shared/useContractorDetailsForm/contractorDetailsSchema.js.map +1 -1
  78. package/dist/components/Contractor/Profile/shared/useContractorDetailsForm/useContractorDetailsForm.d.ts +45 -0
  79. package/dist/components/Contractor/Profile/shared/useContractorDetailsForm/useContractorDetailsForm.js.map +1 -1
  80. package/dist/components/Employee/Compensation/shared/useCompensationForm/compensationSchema.d.ts +1 -0
  81. package/dist/components/Employee/Compensation/shared/useCompensationForm/compensationSchema.js.map +1 -1
  82. package/dist/components/Employee/Dashboard/DashboardFlow.d.ts +1 -1
  83. package/dist/components/Employee/Dashboard/DashboardFlow.js.map +1 -1
  84. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.d.ts +1 -0
  85. package/dist/components/Employee/Deductions/shared/useChildSupportGarnishmentForm/childSupportGarnishmentFormSchema.js.map +1 -1
  86. package/dist/components/Employee/Deductions/shared/useDeductionForm/deductionFormSchema.d.ts +1 -0
  87. package/dist/components/Employee/Deductions/shared/useDeductionForm/deductionFormSchema.js.map +1 -1
  88. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js +5 -3
  89. package/dist/components/Employee/Documents/onboarding/DocumentSigner/DocumentList/useDocumentList.js.map +1 -1
  90. package/dist/components/Employee/Documents/shared/useSignEmployeeForm/signEmployeeFormSchema.d.ts +1 -0
  91. package/dist/components/Employee/Documents/shared/useSignEmployeeForm/signEmployeeFormSchema.js.map +1 -1
  92. package/dist/components/Employee/EmployeeListFlow/EmployeeListFlow.d.ts +2 -2
  93. package/dist/components/Employee/EmployeeListFlow/EmployeeListFlow.js.map +1 -1
  94. package/dist/components/Employee/FederalTaxes/shared/FederalTaxesView.js +1 -1
  95. package/dist/components/Employee/FederalTaxes/shared/useFederalTaxesForm/federalTaxesSchema.d.ts +1 -0
  96. package/dist/components/Employee/FederalTaxes/shared/useFederalTaxesForm/federalTaxesSchema.js.map +1 -1
  97. package/dist/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlow.d.ts +2 -2
  98. package/dist/components/Employee/OnboardingExecutionFlow/OnboardingExecutionFlow.js.map +1 -1
  99. package/dist/components/Employee/OnboardingFlow/OnboardingFlow.d.ts +3 -3
  100. package/dist/components/Employee/OnboardingFlow/OnboardingFlow.js.map +1 -1
  101. package/dist/components/Employee/PaymentMethod/shared/useBankForm/useBankForm.d.ts +4 -4
  102. package/dist/components/Employee/PaymentMethod/shared/useBankForm/useBankForm.js.map +1 -1
  103. package/dist/components/Employee/PaymentMethod/shared/useBankForm/useBankFormSchema.d.ts +1 -0
  104. package/dist/components/Employee/PaymentMethod/shared/useBankForm/useBankFormSchema.js +7 -6
  105. package/dist/components/Employee/PaymentMethod/shared/useBankForm/useBankFormSchema.js.map +1 -1
  106. package/dist/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodForm.d.ts +1 -1
  107. package/dist/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodForm.js.map +1 -1
  108. package/dist/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodFormSchema.d.ts +1 -0
  109. package/dist/components/Employee/PaymentMethod/shared/usePaymentMethodForm/usePaymentMethodFormSchema.js.map +1 -1
  110. package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsForm.d.ts +2 -2
  111. package/dist/components/Employee/PaymentMethod/shared/useSplitPaymentsForm/useSplitPaymentsForm.js.map +1 -1
  112. package/dist/components/Employee/Profile/shared/useEmployeeDetailsForm/employeeDetailsSchema.d.ts +1 -0
  113. package/dist/components/Employee/Profile/shared/useEmployeeDetailsForm/employeeDetailsSchema.js.map +1 -1
  114. package/dist/components/Employee/Profile/shared/useEmployeeDetailsForm/useEmployeeDetailsForm.d.ts +11 -12
  115. package/dist/components/Employee/Profile/shared/useEmployeeDetailsForm/useEmployeeDetailsForm.js.map +1 -1
  116. package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.d.ts +1 -0
  117. package/dist/components/Employee/Profile/shared/useHomeAddressForm/homeAddressSchema.js.map +1 -1
  118. package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.d.ts +36 -0
  119. package/dist/components/Employee/Profile/shared/useHomeAddressForm/useHomeAddressForm.js.map +1 -1
  120. package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.d.ts +31 -0
  121. package/dist/components/Employee/Profile/shared/useWorkAddressForm/useWorkAddressForm.js.map +1 -1
  122. package/dist/components/Employee/Profile/shared/useWorkAddressForm/workAddressSchema.d.ts +1 -0
  123. package/dist/components/Employee/Profile/shared/useWorkAddressForm/workAddressSchema.js.map +1 -1
  124. package/dist/components/Employee/SelfOnboardingFlow/SelfOnboardingFlow.d.ts +2 -2
  125. package/dist/components/Employee/SelfOnboardingFlow/SelfOnboardingFlow.js.map +1 -1
  126. package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fieldProps.d.ts +36 -18
  127. package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.d.ts +113 -13
  128. package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.js.map +1 -1
  129. package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/index.d.ts +1 -1
  130. package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.d.ts +2 -7
  131. package/dist/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.js.map +1 -1
  132. package/dist/components/Flow/Flow.js +1 -1
  133. package/dist/components/InformationRequests/InformationRequests.d.ts +3 -3
  134. package/dist/components/InformationRequests/InformationRequests.js.map +1 -1
  135. package/dist/components/Payroll/usePreparedPayrollData.js +10 -8
  136. package/dist/components/Payroll/usePreparedPayrollData.js.map +1 -1
  137. package/dist/helpers/validations.d.ts +12 -0
  138. package/dist/helpers/validations.js +6 -4
  139. package/dist/helpers/validations.js.map +1 -1
  140. package/dist/index.d.ts +6 -2
  141. package/dist/index.js +247 -237
  142. package/dist/index.js.map +1 -1
  143. package/dist/models/external.d.ts +6 -0
  144. package/dist/style.css +1 -1
  145. package/dist/types/sdkError.js +13 -6
  146. package/dist/types/sdkError.js.map +1 -1
  147. package/package.json +7 -7
  148. package/dist/components/Contractor/PaymentMethod/BankAccountForm.d.ts +0 -3
  149. package/dist/components/Contractor/PaymentMethod/BankAccountForm.js +0 -56
  150. package/dist/components/Contractor/PaymentMethod/BankAccountForm.js.map +0 -1
  151. package/dist/components/Contractor/PaymentMethod/PaymentTypeForm.d.ts +0 -2
  152. package/dist/components/Contractor/PaymentMethod/PaymentTypeForm.js +0 -33
  153. package/dist/components/Contractor/PaymentMethod/PaymentTypeForm.js.map +0 -1
  154. /package/docs/{appendix → guides}/endpoint-inventory.json +0 -0
@@ -32,60 +32,78 @@ export interface BaseStateTaxFieldProps {
32
32
  validationMessages?: StateTaxValidationMessages;
33
33
  }
34
34
  /**
35
- * Props for a `Field` rendered as a select (dropdown).
35
+ * Props for an API-supplied state-tax question rendered as a select (dropdown).
36
+ *
37
+ * Override the user-visible text for this field — its label, description,
38
+ * placeholder, and validation messages.
36
39
  *
37
40
  * @public
38
41
  */
39
- export type SelectStateTaxFieldProps = BaseStateTaxFieldProps & {
42
+ export interface SelectStateTaxFieldProps extends BaseStateTaxFieldProps {
40
43
  /** Placeholder shown when no option is selected. Defaults to a generic localized string when omitted. */
41
44
  placeholder?: string;
42
45
  /** Replace the underlying SDK Select primitive with a component of your own. */
43
46
  FieldComponent?: ComponentType<SelectProps>;
44
- };
47
+ }
45
48
  /**
46
- * Props for a `Field` rendered as a radio group.
49
+ * Props for an API-supplied state-tax question rendered as a radio group.
50
+ *
51
+ * Override the user-visible text for this field — its label, description, and
52
+ * validation messages.
47
53
  *
48
54
  * @public
49
55
  */
50
- export type RadioStateTaxFieldProps = BaseStateTaxFieldProps & {
56
+ export interface RadioStateTaxFieldProps extends BaseStateTaxFieldProps {
51
57
  /** Replace the underlying SDK RadioGroup primitive with a component of your own. */
52
58
  FieldComponent?: ComponentType<RadioGroupProps>;
53
- };
59
+ }
54
60
  /**
55
- * Props for a `Field` rendered as a single-line text input.
61
+ * Props for an API-supplied state-tax question rendered as a single-line text input.
62
+ *
63
+ * Override the user-visible text for this field — its label, description,
64
+ * placeholder, and validation messages.
56
65
  *
57
66
  * @public
58
67
  */
59
- export type TextStateTaxFieldProps = BaseStateTaxFieldProps & {
68
+ export interface TextStateTaxFieldProps extends BaseStateTaxFieldProps {
60
69
  /** Placeholder shown when the field is empty. */
61
70
  placeholder?: string;
62
71
  /** Replace the underlying SDK TextInput primitive with a component of your own. */
63
72
  FieldComponent?: ComponentType<TextInputProps>;
64
- };
73
+ }
65
74
  /**
66
- * Props for a `Field` rendered as a decimal number input.
75
+ * Props for an API-supplied state-tax question rendered as a decimal number input.
76
+ *
77
+ * Override the user-visible text for this field — its label, description, and
78
+ * validation messages.
67
79
  *
68
80
  * @public
69
81
  */
70
- export type NumberStateTaxFieldProps = BaseStateTaxFieldProps & {
82
+ export interface NumberStateTaxFieldProps extends BaseStateTaxFieldProps {
71
83
  /** Replace the underlying SDK NumberInput primitive with a component of your own. */
72
84
  FieldComponent?: ComponentType<NumberInputProps>;
73
- };
85
+ }
74
86
  /**
75
- * Props for a `Field` rendered as a currency-formatted number input.
87
+ * Props for an API-supplied state-tax question rendered as a currency-formatted number input.
88
+ *
89
+ * Override the user-visible text for this field — its label, description, and
90
+ * validation messages.
76
91
  *
77
92
  * @public
78
93
  */
79
- export type CurrencyStateTaxFieldProps = BaseStateTaxFieldProps & {
94
+ export interface CurrencyStateTaxFieldProps extends BaseStateTaxFieldProps {
80
95
  /** Replace the underlying SDK NumberInput primitive with a component of your own. */
81
96
  FieldComponent?: ComponentType<NumberInputProps>;
82
- };
97
+ }
83
98
  /**
84
- * Props for a `Field` rendered as a date picker.
99
+ * Props for an API-supplied state-tax question rendered as a date picker.
100
+ *
101
+ * Override the user-visible text for this field — its label, description, and
102
+ * validation messages.
85
103
  *
86
104
  * @public
87
105
  */
88
- export type DateStateTaxFieldProps = BaseStateTaxFieldProps & {
106
+ export interface DateStateTaxFieldProps extends BaseStateTaxFieldProps {
89
107
  /** Replace the underlying SDK DatePicker primitive with a component of your own. */
90
108
  FieldComponent?: ComponentType<DatePickerProps>;
91
- };
109
+ }
@@ -1,8 +1,14 @@
1
1
  import { ComponentType } from 'react';
2
2
  import { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist';
3
3
  import { CurrencyStateTaxFieldProps, DateStateTaxFieldProps, NumberStateTaxFieldProps, RadioStateTaxFieldProps, SelectStateTaxFieldProps, TextStateTaxFieldProps } from './fieldProps';
4
- export type { CurrencyStateTaxFieldProps, DateStateTaxFieldProps, NumberStateTaxFieldProps, RadioStateTaxFieldProps, SelectStateTaxFieldProps, TextStateTaxFieldProps, } from './fieldProps';
5
- interface SharedQuestionMetadata {
4
+ export type { BaseStateTaxFieldProps, StateTaxValidationMessages, CurrencyStateTaxFieldProps, DateStateTaxFieldProps, NumberStateTaxFieldProps, RadioStateTaxFieldProps, SelectStateTaxFieldProps, TextStateTaxFieldProps, } from './fieldProps';
5
+ /**
6
+ * Metadata shared by every {@link StateTaxQuestionFieldEntry} variant,
7
+ * independent of which input the question renders.
8
+ *
9
+ * @public
10
+ */
11
+ export interface SharedQuestionMetadata {
6
12
  /** Stable identifier for this question (camelCase form of the API key). */
7
13
  questionId: string;
8
14
  /** API-supplied label; default text for the rendered Field. */
@@ -11,37 +17,107 @@ interface SharedQuestionMetadata {
11
17
  description: string | null;
12
18
  }
13
19
  /**
14
- * One question entry within a {@link StateTaxFieldsGroup}, discriminated by
15
- * `type` to identify which input variant the question uses. Each entry carries
16
- * a `Field` component pre-bound to its API-supplied metadata so callers can
17
- * render the input directly.
20
+ * A state-tax question that renders as a select (dropdown). Includes read-only
21
+ * question metadata from the API and a bound select field, exposed as
22
+ * `<question.Field />`.
18
23
  *
19
24
  * @public
25
+ * @group Fields
20
26
  */
21
- export type StateTaxQuestionFieldEntry = ({
27
+ export interface SelectStateTaxQuestion extends SharedQuestionMetadata {
28
+ /** Discriminant identifying the select variant. */
22
29
  type: 'select';
30
+ /** Field component pre-bound to this question's API-supplied metadata. */
23
31
  Field: ComponentType<SelectStateTaxFieldProps>;
24
- } & SharedQuestionMetadata) | ({
32
+ }
33
+ /**
34
+ * A state-tax question that renders as a radio group. Includes read-only
35
+ * question metadata from the API and a bound radio field, exposed as
36
+ * `<question.Field />`.
37
+ *
38
+ * @public
39
+ * @group Fields
40
+ */
41
+ export interface RadioStateTaxQuestion extends SharedQuestionMetadata {
42
+ /** Discriminant identifying the radio variant. */
25
43
  type: 'radio';
44
+ /** Field component pre-bound to this question's API-supplied metadata. */
26
45
  Field: ComponentType<RadioStateTaxFieldProps>;
27
- } & SharedQuestionMetadata) | ({
46
+ }
47
+ /**
48
+ * A state-tax question that renders as a single-line text input. Includes
49
+ * read-only question metadata from the API and a bound text field, exposed as
50
+ * `<question.Field />`.
51
+ *
52
+ * @public
53
+ * @group Fields
54
+ */
55
+ export interface TextStateTaxQuestion extends SharedQuestionMetadata {
56
+ /** Discriminant identifying the text variant. */
28
57
  type: 'text';
58
+ /** Field component pre-bound to this question's API-supplied metadata. */
29
59
  Field: ComponentType<TextStateTaxFieldProps>;
30
- } & SharedQuestionMetadata) | ({
60
+ }
61
+ /**
62
+ * A state-tax question that renders as a decimal number input. Includes
63
+ * read-only question metadata from the API and a bound number field, exposed as
64
+ * `<question.Field />`.
65
+ *
66
+ * @public
67
+ * @group Fields
68
+ */
69
+ export interface NumberStateTaxQuestion extends SharedQuestionMetadata {
70
+ /** Discriminant identifying the number variant. */
31
71
  type: 'number';
72
+ /** Field component pre-bound to this question's API-supplied metadata. */
32
73
  Field: ComponentType<NumberStateTaxFieldProps>;
33
- } & SharedQuestionMetadata) | ({
74
+ }
75
+ /**
76
+ * A state-tax question that renders as a currency-formatted number input. Includes
77
+ * read-only question metadata from the API and a bound currency field, exposed as
78
+ * `<question.Field />`.
79
+ *
80
+ * @public
81
+ * @group Fields
82
+ */
83
+ export interface CurrencyStateTaxQuestion extends SharedQuestionMetadata {
84
+ /** Discriminant identifying the currency variant. */
34
85
  type: 'currency';
86
+ /** Field component pre-bound to this question's API-supplied metadata. */
35
87
  Field: ComponentType<CurrencyStateTaxFieldProps>;
36
- } & SharedQuestionMetadata) | ({
88
+ }
89
+ /**
90
+ * A state-tax question that renders as a date picker. Includes read-only
91
+ * question metadata from the API and a bound date field, exposed as
92
+ * `<question.Field />`.
93
+ *
94
+ * @public
95
+ * @group Fields
96
+ */
97
+ export interface DateStateTaxQuestion extends SharedQuestionMetadata {
98
+ /** Discriminant identifying the date variant. */
37
99
  type: 'date';
100
+ /** Field component pre-bound to this question's API-supplied metadata. */
38
101
  Field: ComponentType<DateStateTaxFieldProps>;
39
- } & SharedQuestionMetadata);
102
+ }
103
+ /**
104
+ * One question entry within a {@link StateTaxFieldsGroup}, discriminated by
105
+ * `type` to identify which input variant the question uses. Each entry carries
106
+ * a `Field` component pre-bound to its API-supplied metadata so callers can
107
+ * render the input directly.
108
+ *
109
+ * @public
110
+ * @group Fields
111
+ * @groupWith {@link StateTaxFieldsGroup}
112
+ */
113
+ export type StateTaxQuestionFieldEntry = SelectStateTaxQuestion | RadioStateTaxQuestion | TextStateTaxQuestion | NumberStateTaxQuestion | CurrencyStateTaxQuestion | DateStateTaxQuestion;
40
114
  /**
41
115
  * Group of state-tax questions for a single jurisdiction returned by
42
116
  * {@link useStateFields}.
43
117
  *
44
118
  * @public
119
+ * @group Fields
120
+ * @groupWith {@link StateTaxFields}
45
121
  */
46
122
  export interface StateTaxFieldsGroup {
47
123
  /** Two-letter state code. */
@@ -49,6 +125,30 @@ export interface StateTaxFieldsGroup {
49
125
  /** Ordered list of question entries for this state, post admin-only filtering. */
50
126
  questions: StateTaxQuestionFieldEntry[];
51
127
  }
128
+ /**
129
+ * Iterable, render-ready group + question entries with bound Field components,
130
+ * grouped by state.
131
+ *
132
+ * @public
133
+ *
134
+ * @example
135
+ * The value exposed on `form.Fields`: one entry per state, each carrying its
136
+ * questions as pre-bound `Field` components you render directly.
137
+ *
138
+ * ```tsx
139
+ * function StateTaxQuestions({ fields }: { fields: StateTaxFields }) {
140
+ * return fields.map(group => (
141
+ * <section key={group.state}>
142
+ * <h3>{group.state}</h3>
143
+ * {group.questions.map(question => (
144
+ * <question.Field key={question.questionId} />
145
+ * ))}
146
+ * </section>
147
+ * ))
148
+ * }
149
+ * ```
150
+ */
151
+ export type StateTaxFields = StateTaxFieldsGroup[];
52
152
  /** @internal */
53
153
  export interface CreateStateFieldsOptions {
54
154
  isAdmin: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"fields.js","sources":["../../../../../../src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\nimport { useMemo } from 'react'\nimport type { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist'\nimport { getQuestionVariant, type StateTaxQuestionVariant } from './fieldMapping'\nimport {\n CurrencyStateTaxField,\n DateStateTaxField,\n NumberStateTaxField,\n RadioStateTaxField,\n SelectStateTaxField,\n TextStateTaxField,\n} from './fieldComponents'\nimport type { BoundFieldMeta } from './fieldMeta'\nimport type {\n CurrencyStateTaxFieldProps,\n DateStateTaxFieldProps,\n NumberStateTaxFieldProps,\n RadioStateTaxFieldProps,\n SelectStateTaxFieldProps,\n TextStateTaxFieldProps,\n} from './fieldProps'\nimport { snakeCaseToCamelCase } from '@/helpers/formattedStrings'\n\nexport type {\n CurrencyStateTaxFieldProps,\n DateStateTaxFieldProps,\n NumberStateTaxFieldProps,\n RadioStateTaxFieldProps,\n SelectStateTaxFieldProps,\n TextStateTaxFieldProps,\n} from './fieldProps'\n\n// ── Discriminated union surfaced to partners ───────────────────────────\n\ninterface SharedQuestionMetadata {\n /** Stable identifier for this question (camelCase form of the API key). */\n questionId: string\n /** API-supplied label; default text for the rendered Field. */\n label: string\n /** API-supplied description (raw HTML, sanitized internally before render). */\n description: string | null\n}\n\n/**\n * One question entry within a {@link StateTaxFieldsGroup}, discriminated by\n * `type` to identify which input variant the question uses. Each entry carries\n * a `Field` component pre-bound to its API-supplied metadata so callers can\n * render the input directly.\n *\n * @public\n */\nexport type StateTaxQuestionFieldEntry =\n | ({ type: 'select'; Field: ComponentType<SelectStateTaxFieldProps> } & SharedQuestionMetadata)\n | ({ type: 'radio'; Field: ComponentType<RadioStateTaxFieldProps> } & SharedQuestionMetadata)\n | ({ type: 'text'; Field: ComponentType<TextStateTaxFieldProps> } & SharedQuestionMetadata)\n | ({ type: 'number'; Field: ComponentType<NumberStateTaxFieldProps> } & SharedQuestionMetadata)\n | ({\n type: 'currency'\n Field: ComponentType<CurrencyStateTaxFieldProps>\n } & SharedQuestionMetadata)\n | ({ type: 'date'; Field: ComponentType<DateStateTaxFieldProps> } & SharedQuestionMetadata)\n\n/**\n * Group of state-tax questions for a single jurisdiction returned by\n * {@link useStateFields}.\n *\n * @public\n */\nexport interface StateTaxFieldsGroup {\n /** Two-letter state code. */\n state: string\n /** Ordered list of question entries for this state, post admin-only filtering. */\n questions: StateTaxQuestionFieldEntry[]\n}\n\n// ── Factory ────────────────────────────────────────────────────────────\n\n/** @internal */\nexport interface CreateStateFieldsOptions {\n isAdmin: boolean\n}\n\n/** @internal */\nexport function createStateFields(\n employeeStateTaxes: EmployeeStateTaxesList[],\n options: CreateStateFieldsOptions,\n): StateTaxFieldsGroup[] {\n const { isAdmin } = options\n const groups: StateTaxFieldsGroup[] = []\n\n for (const stateGroup of employeeStateTaxes) {\n if (!stateGroup.state || !stateGroup.questions) continue\n\n const questions: StateTaxQuestionFieldEntry[] = []\n for (const question of stateGroup.questions) {\n if (question.isQuestionForAdminOnly && !isAdmin) continue\n\n const formKey = snakeCaseToCamelCase(question.key)\n const meta: BoundFieldMeta = {\n name: `states.${stateGroup.state}.${formKey}`,\n apiLabel: question.label,\n apiDescription: question.description,\n }\n const variant = getQuestionVariant(question)\n const shared: SharedQuestionMetadata = {\n questionId: formKey,\n label: question.label,\n description: question.description,\n }\n\n questions.push(buildEntry(variant, meta, shared))\n }\n\n if (questions.length === 0) continue\n\n groups.push({\n state: stateGroup.state,\n questions,\n })\n }\n\n return groups\n}\n\nfunction buildEntry(\n variant: StateTaxQuestionVariant,\n meta: BoundFieldMeta,\n shared: SharedQuestionMetadata,\n): StateTaxQuestionFieldEntry {\n switch (variant) {\n case 'select':\n return {\n type: 'select',\n Field: function BoundSelectStateTaxField(props: SelectStateTaxFieldProps) {\n return <SelectStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'radio':\n return {\n type: 'radio',\n Field: function BoundRadioStateTaxField(props: RadioStateTaxFieldProps) {\n return <RadioStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'text':\n return {\n type: 'text',\n Field: function BoundTextStateTaxField(props: TextStateTaxFieldProps) {\n return <TextStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'number':\n return {\n type: 'number',\n Field: function BoundNumberStateTaxField(props: NumberStateTaxFieldProps) {\n return <NumberStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'currency':\n return {\n type: 'currency',\n Field: function BoundCurrencyStateTaxField(props: CurrencyStateTaxFieldProps) {\n return <CurrencyStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'date':\n return {\n type: 'date',\n Field: function BoundDateStateTaxField(props: DateStateTaxFieldProps) {\n return <DateStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n }\n}\n\n/**\n * Memoizes the bound field components for a state-taxes form, avoiding unnecessary rebuilds when the data refetches but the underlying questions haven't changed.\n *\n * @param employeeStateTaxes - Array of state-tax groups returned by the employee state-taxes API.\n * @param isAdmin - When `true`, admin-only questions are included; when `false`, they are filtered out.\n * @returns An array of {@link StateTaxFieldsGroup} — one entry per state, each with a `questions` array of bound field components.\n * @public\n * @group Utility Hooks\n */\nexport function useStateFields(\n employeeStateTaxes: EmployeeStateTaxesList[],\n isAdmin: boolean,\n): StateTaxFieldsGroup[] {\n return useMemo(\n () => createStateFields(employeeStateTaxes, { isAdmin }),\n [employeeStateTaxes, isAdmin],\n )\n}\n"],"names":["createStateFields","employeeStateTaxes","options","isAdmin","groups","stateGroup","questions","question","formKey","snakeCaseToCamelCase","meta","variant","getQuestionVariant","shared","buildEntry","props","jsx","SelectStateTaxField","RadioStateTaxField","TextStateTaxField","NumberStateTaxField","CurrencyStateTaxField","DateStateTaxField","useStateFields","useMemo"],"mappings":";;;;;AAmFO,SAASA,EACdC,GACAC,GACuB;AACvB,QAAM,EAAE,SAAAC,MAAYD,GACdE,IAAgC,CAAA;AAEtC,aAAWC,KAAcJ,GAAoB;AAC3C,QAAI,CAACI,EAAW,SAAS,CAACA,EAAW,UAAW;AAEhD,UAAMC,IAA0C,CAAA;AAChD,eAAWC,KAAYF,EAAW,WAAW;AAC3C,UAAIE,EAAS,0BAA0B,CAACJ,EAAS;AAEjD,YAAMK,IAAUC,EAAqBF,EAAS,GAAG,GAC3CG,IAAuB;AAAA,QAC3B,MAAM,UAAUL,EAAW,KAAK,IAAIG,CAAO;AAAA,QAC3C,UAAUD,EAAS;AAAA,QACnB,gBAAgBA,EAAS;AAAA,MAAA,GAErBI,IAAUC,EAAmBL,CAAQ,GACrCM,IAAiC;AAAA,QACrC,YAAYL;AAAA,QACZ,OAAOD,EAAS;AAAA,QAChB,aAAaA,EAAS;AAAA,MAAA;AAGxB,MAAAD,EAAU,KAAKQ,EAAWH,GAASD,GAAMG,CAAM,CAAC;AAAA,IAClD;AAEA,IAAIP,EAAU,WAAW,KAEzBF,EAAO,KAAK;AAAA,MACV,OAAOC,EAAW;AAAA,MAClB,WAAAC;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SAAOF;AACT;AAEA,SAASU,EACPH,GACAD,GACAG,GAC4B;AAC5B,UAAQF,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAkCI,GAAiC;AACxE,iBAAO,gBAAAC,EAACC,GAAA,EAAoB,MAAAP,GAAa,GAAGK,EAAA,CAAO;AAAA,QACrD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAiCE,GAAgC;AACtE,iBAAO,gBAAAC,EAACE,GAAA,EAAmB,MAAAR,GAAa,GAAGK,EAAA,CAAO;AAAA,QACpD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAgCE,GAA+B;AACpE,iBAAO,gBAAAC,EAACG,GAAA,EAAkB,MAAAT,GAAa,GAAGK,EAAA,CAAO;AAAA,QACnD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAkCE,GAAiC;AACxE,iBAAO,gBAAAC,EAACI,GAAA,EAAoB,MAAAV,GAAa,GAAGK,EAAA,CAAO;AAAA,QACrD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAoCE,GAAmC;AAC5E,iBAAO,gBAAAC,EAACK,GAAA,EAAsB,MAAAX,GAAa,GAAGK,EAAA,CAAO;AAAA,QACvD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAgCE,GAA+B;AACpE,iBAAO,gBAAAC,EAACM,GAAA,EAAkB,MAAAZ,GAAa,GAAGK,EAAA,CAAO;AAAA,QACnD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,EACL;AAEN;AAWO,SAASU,EACdtB,GACAE,GACuB;AACvB,SAAOqB;AAAA,IACL,MAAMxB,EAAkBC,GAAoB,EAAE,SAAAE,GAAS;AAAA,IACvD,CAACF,GAAoBE,CAAO;AAAA,EAAA;AAEhC;"}
1
+ {"version":3,"file":"fields.js","sources":["../../../../../../src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/fields.tsx"],"sourcesContent":["import type { ComponentType } from 'react'\nimport { useMemo } from 'react'\nimport type { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist'\nimport { getQuestionVariant, type StateTaxQuestionVariant } from './fieldMapping'\nimport {\n CurrencyStateTaxField,\n DateStateTaxField,\n NumberStateTaxField,\n RadioStateTaxField,\n SelectStateTaxField,\n TextStateTaxField,\n} from './fieldComponents'\nimport type { BoundFieldMeta } from './fieldMeta'\nimport type {\n CurrencyStateTaxFieldProps,\n DateStateTaxFieldProps,\n NumberStateTaxFieldProps,\n RadioStateTaxFieldProps,\n SelectStateTaxFieldProps,\n TextStateTaxFieldProps,\n} from './fieldProps'\nimport { snakeCaseToCamelCase } from '@/helpers/formattedStrings'\n\nexport type {\n BaseStateTaxFieldProps,\n StateTaxValidationMessages,\n CurrencyStateTaxFieldProps,\n DateStateTaxFieldProps,\n NumberStateTaxFieldProps,\n RadioStateTaxFieldProps,\n SelectStateTaxFieldProps,\n TextStateTaxFieldProps,\n} from './fieldProps'\n\n// ── Discriminated union surfaced to partners ───────────────────────────\n\n/**\n * Metadata shared by every {@link StateTaxQuestionFieldEntry} variant,\n * independent of which input the question renders.\n *\n * @public\n */\nexport interface SharedQuestionMetadata {\n /** Stable identifier for this question (camelCase form of the API key). */\n questionId: string\n /** API-supplied label; default text for the rendered Field. */\n label: string\n /** API-supplied description (raw HTML, sanitized internally before render). */\n description: string | null\n}\n\n/**\n * A state-tax question that renders as a select (dropdown). Includes read-only\n * question metadata from the API and a bound select field, exposed as\n * `<question.Field />`.\n *\n * @public\n * @group Fields\n */\nexport interface SelectStateTaxQuestion extends SharedQuestionMetadata {\n /** Discriminant identifying the select variant. */\n type: 'select'\n /** Field component pre-bound to this question's API-supplied metadata. */\n Field: ComponentType<SelectStateTaxFieldProps>\n}\n\n/**\n * A state-tax question that renders as a radio group. Includes read-only\n * question metadata from the API and a bound radio field, exposed as\n * `<question.Field />`.\n *\n * @public\n * @group Fields\n */\nexport interface RadioStateTaxQuestion extends SharedQuestionMetadata {\n /** Discriminant identifying the radio variant. */\n type: 'radio'\n /** Field component pre-bound to this question's API-supplied metadata. */\n Field: ComponentType<RadioStateTaxFieldProps>\n}\n\n/**\n * A state-tax question that renders as a single-line text input. Includes\n * read-only question metadata from the API and a bound text field, exposed as\n * `<question.Field />`.\n *\n * @public\n * @group Fields\n */\nexport interface TextStateTaxQuestion extends SharedQuestionMetadata {\n /** Discriminant identifying the text variant. */\n type: 'text'\n /** Field component pre-bound to this question's API-supplied metadata. */\n Field: ComponentType<TextStateTaxFieldProps>\n}\n\n/**\n * A state-tax question that renders as a decimal number input. Includes\n * read-only question metadata from the API and a bound number field, exposed as\n * `<question.Field />`.\n *\n * @public\n * @group Fields\n */\nexport interface NumberStateTaxQuestion extends SharedQuestionMetadata {\n /** Discriminant identifying the number variant. */\n type: 'number'\n /** Field component pre-bound to this question's API-supplied metadata. */\n Field: ComponentType<NumberStateTaxFieldProps>\n}\n\n/**\n * A state-tax question that renders as a currency-formatted number input. Includes\n * read-only question metadata from the API and a bound currency field, exposed as\n * `<question.Field />`.\n *\n * @public\n * @group Fields\n */\nexport interface CurrencyStateTaxQuestion extends SharedQuestionMetadata {\n /** Discriminant identifying the currency variant. */\n type: 'currency'\n /** Field component pre-bound to this question's API-supplied metadata. */\n Field: ComponentType<CurrencyStateTaxFieldProps>\n}\n\n/**\n * A state-tax question that renders as a date picker. Includes read-only\n * question metadata from the API and a bound date field, exposed as\n * `<question.Field />`.\n *\n * @public\n * @group Fields\n */\nexport interface DateStateTaxQuestion extends SharedQuestionMetadata {\n /** Discriminant identifying the date variant. */\n type: 'date'\n /** Field component pre-bound to this question's API-supplied metadata. */\n Field: ComponentType<DateStateTaxFieldProps>\n}\n\n/**\n * One question entry within a {@link StateTaxFieldsGroup}, discriminated by\n * `type` to identify which input variant the question uses. Each entry carries\n * a `Field` component pre-bound to its API-supplied metadata so callers can\n * render the input directly.\n *\n * @public\n * @group Fields\n * @groupWith {@link StateTaxFieldsGroup}\n */\nexport type StateTaxQuestionFieldEntry =\n | SelectStateTaxQuestion\n | RadioStateTaxQuestion\n | TextStateTaxQuestion\n | NumberStateTaxQuestion\n | CurrencyStateTaxQuestion\n | DateStateTaxQuestion\n\n/**\n * Group of state-tax questions for a single jurisdiction returned by\n * {@link useStateFields}.\n *\n * @public\n * @group Fields\n * @groupWith {@link StateTaxFields}\n */\nexport interface StateTaxFieldsGroup {\n /** Two-letter state code. */\n state: string\n /** Ordered list of question entries for this state, post admin-only filtering. */\n questions: StateTaxQuestionFieldEntry[]\n}\n\n/**\n * Iterable, render-ready group + question entries with bound Field components,\n * grouped by state.\n *\n * @public\n *\n * @example\n * The value exposed on `form.Fields`: one entry per state, each carrying its\n * questions as pre-bound `Field` components you render directly.\n *\n * ```tsx\n * function StateTaxQuestions({ fields }: { fields: StateTaxFields }) {\n * return fields.map(group => (\n * <section key={group.state}>\n * <h3>{group.state}</h3>\n * {group.questions.map(question => (\n * <question.Field key={question.questionId} />\n * ))}\n * </section>\n * ))\n * }\n * ```\n */\nexport type StateTaxFields = StateTaxFieldsGroup[]\n\n// ── Factory ────────────────────────────────────────────────────────────\n\n/** @internal */\nexport interface CreateStateFieldsOptions {\n isAdmin: boolean\n}\n\n/** @internal */\nexport function createStateFields(\n employeeStateTaxes: EmployeeStateTaxesList[],\n options: CreateStateFieldsOptions,\n): StateTaxFieldsGroup[] {\n const { isAdmin } = options\n const groups: StateTaxFieldsGroup[] = []\n\n for (const stateGroup of employeeStateTaxes) {\n if (!stateGroup.state || !stateGroup.questions) continue\n\n const questions: StateTaxQuestionFieldEntry[] = []\n for (const question of stateGroup.questions) {\n if (question.isQuestionForAdminOnly && !isAdmin) continue\n\n const formKey = snakeCaseToCamelCase(question.key)\n const meta: BoundFieldMeta = {\n name: `states.${stateGroup.state}.${formKey}`,\n apiLabel: question.label,\n apiDescription: question.description,\n }\n const variant = getQuestionVariant(question)\n const shared: SharedQuestionMetadata = {\n questionId: formKey,\n label: question.label,\n description: question.description,\n }\n\n questions.push(buildEntry(variant, meta, shared))\n }\n\n if (questions.length === 0) continue\n\n groups.push({\n state: stateGroup.state,\n questions,\n })\n }\n\n return groups\n}\n\nfunction buildEntry(\n variant: StateTaxQuestionVariant,\n meta: BoundFieldMeta,\n shared: SharedQuestionMetadata,\n): StateTaxQuestionFieldEntry {\n switch (variant) {\n case 'select':\n return {\n type: 'select',\n Field: function BoundSelectStateTaxField(props: SelectStateTaxFieldProps) {\n return <SelectStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'radio':\n return {\n type: 'radio',\n Field: function BoundRadioStateTaxField(props: RadioStateTaxFieldProps) {\n return <RadioStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'text':\n return {\n type: 'text',\n Field: function BoundTextStateTaxField(props: TextStateTaxFieldProps) {\n return <TextStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'number':\n return {\n type: 'number',\n Field: function BoundNumberStateTaxField(props: NumberStateTaxFieldProps) {\n return <NumberStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'currency':\n return {\n type: 'currency',\n Field: function BoundCurrencyStateTaxField(props: CurrencyStateTaxFieldProps) {\n return <CurrencyStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n case 'date':\n return {\n type: 'date',\n Field: function BoundDateStateTaxField(props: DateStateTaxFieldProps) {\n return <DateStateTaxField meta={meta} {...props} />\n },\n ...shared,\n }\n }\n}\n\n/**\n * Memoizes the bound field components for a state-taxes form, avoiding unnecessary rebuilds when the data refetches but the underlying questions haven't changed.\n *\n * @param employeeStateTaxes - Array of state-tax groups returned by the employee state-taxes API.\n * @param isAdmin - When `true`, admin-only questions are included; when `false`, they are filtered out.\n * @returns An array of {@link StateTaxFieldsGroup} — one entry per state, each with a `questions` array of bound field components.\n * @public\n * @group Utility Hooks\n */\nexport function useStateFields(\n employeeStateTaxes: EmployeeStateTaxesList[],\n isAdmin: boolean,\n): StateTaxFieldsGroup[] {\n return useMemo(\n () => createStateFields(employeeStateTaxes, { isAdmin }),\n [employeeStateTaxes, isAdmin],\n )\n}\n"],"names":["createStateFields","employeeStateTaxes","options","isAdmin","groups","stateGroup","questions","question","formKey","snakeCaseToCamelCase","meta","variant","getQuestionVariant","shared","buildEntry","props","jsx","SelectStateTaxField","RadioStateTaxField","TextStateTaxField","NumberStateTaxField","CurrencyStateTaxField","DateStateTaxField","useStateFields","useMemo"],"mappings":";;;;;AA+MO,SAASA,EACdC,GACAC,GACuB;AACvB,QAAM,EAAE,SAAAC,MAAYD,GACdE,IAAgC,CAAA;AAEtC,aAAWC,KAAcJ,GAAoB;AAC3C,QAAI,CAACI,EAAW,SAAS,CAACA,EAAW,UAAW;AAEhD,UAAMC,IAA0C,CAAA;AAChD,eAAWC,KAAYF,EAAW,WAAW;AAC3C,UAAIE,EAAS,0BAA0B,CAACJ,EAAS;AAEjD,YAAMK,IAAUC,EAAqBF,EAAS,GAAG,GAC3CG,IAAuB;AAAA,QAC3B,MAAM,UAAUL,EAAW,KAAK,IAAIG,CAAO;AAAA,QAC3C,UAAUD,EAAS;AAAA,QACnB,gBAAgBA,EAAS;AAAA,MAAA,GAErBI,IAAUC,EAAmBL,CAAQ,GACrCM,IAAiC;AAAA,QACrC,YAAYL;AAAA,QACZ,OAAOD,EAAS;AAAA,QAChB,aAAaA,EAAS;AAAA,MAAA;AAGxB,MAAAD,EAAU,KAAKQ,EAAWH,GAASD,GAAMG,CAAM,CAAC;AAAA,IAClD;AAEA,IAAIP,EAAU,WAAW,KAEzBF,EAAO,KAAK;AAAA,MACV,OAAOC,EAAW;AAAA,MAClB,WAAAC;AAAA,IAAA,CACD;AAAA,EACH;AAEA,SAAOF;AACT;AAEA,SAASU,EACPH,GACAD,GACAG,GAC4B;AAC5B,UAAQF,GAAA;AAAA,IACN,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAkCI,GAAiC;AACxE,iBAAO,gBAAAC,EAACC,GAAA,EAAoB,MAAAP,GAAa,GAAGK,EAAA,CAAO;AAAA,QACrD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAiCE,GAAgC;AACtE,iBAAO,gBAAAC,EAACE,GAAA,EAAmB,MAAAR,GAAa,GAAGK,EAAA,CAAO;AAAA,QACpD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAgCE,GAA+B;AACpE,iBAAO,gBAAAC,EAACG,GAAA,EAAkB,MAAAT,GAAa,GAAGK,EAAA,CAAO;AAAA,QACnD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAkCE,GAAiC;AACxE,iBAAO,gBAAAC,EAACI,GAAA,EAAoB,MAAAV,GAAa,GAAGK,EAAA,CAAO;AAAA,QACrD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAoCE,GAAmC;AAC5E,iBAAO,gBAAAC,EAACK,GAAA,EAAsB,MAAAX,GAAa,GAAGK,EAAA,CAAO;AAAA,QACvD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,IAEP,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,SAAgCE,GAA+B;AACpE,iBAAO,gBAAAC,EAACM,GAAA,EAAkB,MAAAZ,GAAa,GAAGK,EAAA,CAAO;AAAA,QACnD;AAAA,QACA,GAAGF;AAAA,MAAA;AAAA,EACL;AAEN;AAWO,SAASU,EACdtB,GACAE,GACuB;AACvB,SAAOqB;AAAA,IACL,MAAMxB,EAAkBC,GAAoB,EAAE,SAAAE,GAAS;AAAA,IACvD,CAACF,GAAoBE,CAAO;AAAA,EAAA;AAEhC;"}
@@ -2,5 +2,5 @@ import "./types/i18next.d.ts"
2
2
  export { useEmployeeStateTaxesForm } from './useEmployeeStateTaxesForm';
3
3
  export type { UseEmployeeStateTaxesFormProps, UseEmployeeStateTaxesFormResult, UseEmployeeStateTaxesFormReady, EmployeeStateTaxesFieldsMetadata, EmployeeStateTaxesFormFields, } from './useEmployeeStateTaxesForm';
4
4
  export { createEmployeeStateTaxesSchema, EmployeeStateTaxesErrorCodes, type EmployeeStateTaxesErrorCode, type EmployeeStateTaxesFormData, type EmployeeStateTaxesFormOutputs, type EmployeeStateTaxesSchemaOptions, type EmployeeStateTaxesQuestionMeta, type EmployeeStateTaxesMetadataConfig, type StateTaxValue, } from './employeeStateTaxesSchema';
5
- export { createStateFields, useStateFields, type CreateStateFieldsOptions, type StateTaxFieldsGroup, type StateTaxQuestionFieldEntry, type SelectStateTaxFieldProps, type RadioStateTaxFieldProps, type TextStateTaxFieldProps, type NumberStateTaxFieldProps, type CurrencyStateTaxFieldProps, type DateStateTaxFieldProps, } from './fields';
5
+ export { createStateFields, useStateFields, type CreateStateFieldsOptions, type StateTaxFields, type StateTaxFieldsGroup, type StateTaxQuestionFieldEntry, type SharedQuestionMetadata, type SelectStateTaxQuestion, type RadioStateTaxQuestion, type TextStateTaxQuestion, type NumberStateTaxQuestion, type CurrencyStateTaxQuestion, type DateStateTaxQuestion, type BaseStateTaxFieldProps, type StateTaxValidationMessages, type SelectStateTaxFieldProps, type RadioStateTaxFieldProps, type TextStateTaxFieldProps, type NumberStateTaxFieldProps, type CurrencyStateTaxFieldProps, type DateStateTaxFieldProps, } from './fields';
6
6
  export { getQuestionVariant, type StateTaxQuestionVariant } from './fieldMapping';
@@ -1,7 +1,7 @@
1
1
  import { UseFormProps } from 'react-hook-form';
2
2
  import { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist';
3
3
  import { EmployeeStateTaxesFormData } from './employeeStateTaxesSchema';
4
- import { StateTaxFieldsGroup } from './fields';
4
+ import { StateTaxFields } from './fields';
5
5
  import { BaseFormHookReady, FieldsMetadata, HookLoadingResult, HookSubmitResult } from '../../../../../partner-hook-utils/types';
6
6
  /**
7
7
  * Options accepted by {@link useEmployeeStateTaxesForm}.
@@ -28,7 +28,7 @@ export interface UseEmployeeStateTaxesFormProps {
28
28
  *
29
29
  * @public
30
30
  */
31
- export interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady<FieldsMetadata, EmployeeStateTaxesFormData, StateTaxFieldsGroup[]> {
31
+ export interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady<FieldsMetadata, EmployeeStateTaxesFormData, StateTaxFields> {
32
32
  /** Current per-state tax records returned by the server. */
33
33
  data: {
34
34
  employeeStateTaxes: EmployeeStateTaxesList[];
@@ -43,11 +43,6 @@ export interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady<Fields
43
43
  /** Validates and submits the form, resolving to the updated records on success or `undefined` when validation blocked the submit. */
44
44
  onSubmit: () => Promise<HookSubmitResult<EmployeeStateTaxesList[]> | undefined>;
45
45
  };
46
- /** Form internals plus the iterable per-state `Fields` array. */
47
- form: BaseFormHookReady<FieldsMetadata, EmployeeStateTaxesFormData, StateTaxFieldsGroup[]>['form'] & {
48
- /** Iterable, render-ready group + question entries with bound Field components. */
49
- Fields: StateTaxFieldsGroup[];
50
- };
51
46
  }
52
47
  /**
53
48
  * Discriminated union returned by {@link useEmployeeStateTaxesForm}. Loading
@@ -1 +1 @@
1
- {"version":3,"file":"useEmployeeStateTaxesForm.js","sources":["../../../../../../src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.tsx"],"sourcesContent":["import { useMemo } from 'react'\nimport { useForm } from 'react-hook-form'\nimport type { UseFormProps } from 'react-hook-form'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport type { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist'\nimport type {\n EmployeeStateTaxesRequest,\n States as EmployeeStateTaxesRequestState,\n} from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxesrequest'\nimport { useEmployeeTaxSetupGetStateTaxes } from '@gusto/embedded-api-v-2025-11-15/react-query/employeeTaxSetupGetStateTaxes'\nimport { useEmployeeTaxSetupUpdateStateTaxesMutation } from '@gusto/embedded-api-v-2025-11-15/react-query/employeeTaxSetupUpdateStateTaxes'\nimport {\n createEmployeeStateTaxesSchema,\n type EmployeeStateTaxesFormData,\n type EmployeeStateTaxesFormOutputs,\n type EmployeeStateTaxesMetadataConfig,\n} from './employeeStateTaxesSchema'\nimport { createStateFields, type StateTaxFieldsGroup } from './fields'\nimport { getQuestionVariant } from './fieldMapping'\nimport { snakeCaseToCamelCase } from '@/helpers/formattedStrings'\nimport { useDeriveFieldsMetadata } from '@/partner-hook-utils/form/useDeriveFieldsMetadata'\nimport { createGetFormSubmissionValues } from '@/partner-hook-utils/form/getFormSubmissionValues'\nimport { useHookFormInternals } from '@/partner-hook-utils/form/useHookFormInternals'\nimport { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler'\nimport type {\n BaseFormHookReady,\n FieldsMetadata,\n HookLoadingResult,\n HookSubmitResult,\n} from '@/partner-hook-utils/types'\nimport { useBaseSubmit } from '@/components/Base/useBaseSubmit'\nimport { SDKInternalError } from '@/types/sdkError'\n\nconst DEFAULT_TAX_VALID_FROM = '2010-01-01'\n\n/**\n * Options accepted by {@link useEmployeeStateTaxesForm}.\n *\n * @public\n */\nexport interface UseEmployeeStateTaxesFormProps {\n /** The UUID of the employee whose state taxes are being updated. */\n employeeId: string\n /**\n * When `true`, admin-only questions are visible and submitted. When\n * `false`, they are filtered out and the surfaced answer for those\n * questions is preserved unchanged on submit.\n */\n isAdmin?: boolean\n /** When validation runs. Passed through to react-hook-form. Defaults to `'onSubmit'`. */\n validationMode?: UseFormProps['mode']\n /** Auto-focus the first invalid field on submit. Defaults to `true`. Set to `false` when composing with other forms. */\n shouldFocusError?: boolean\n}\n\n/**\n * Ready-state return value of {@link useEmployeeStateTaxesForm} — the\n * `isLoading: false` branch of {@link UseEmployeeStateTaxesFormResult}.\n *\n * @public\n */\nexport interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady<\n FieldsMetadata,\n EmployeeStateTaxesFormData,\n StateTaxFieldsGroup[]\n> {\n /** Current per-state tax records returned by the server. */\n data: {\n employeeStateTaxes: EmployeeStateTaxesList[]\n }\n /** Submission status. `mode` is always `'update'` since state-tax records are created with the employee. */\n status: { isPending: boolean; mode: 'update' }\n /** Form actions. */\n actions: {\n /** Validates and submits the form, resolving to the updated records on success or `undefined` when validation blocked the submit. */\n onSubmit: () => Promise<HookSubmitResult<EmployeeStateTaxesList[]> | undefined>\n }\n /** Form internals plus the iterable per-state `Fields` array. */\n form: BaseFormHookReady<\n FieldsMetadata,\n EmployeeStateTaxesFormData,\n StateTaxFieldsGroup[]\n >['form'] & {\n /** Iterable, render-ready group + question entries with bound Field components. */\n Fields: StateTaxFieldsGroup[]\n }\n}\n\n/**\n * Discriminated union returned by {@link useEmployeeStateTaxesForm}. Loading\n * branch carries only `errorHandling`; ready branch carries form data,\n * fields, status, and actions.\n *\n * @public\n */\nexport type UseEmployeeStateTaxesFormResult = HookLoadingResult | UseEmployeeStateTaxesFormReady\n\n/**\n * Headless form hook for updating an employee's state tax withholding answers.\n * The set of questions is driven by the API response per state, so\n * `form.Fields` is an array of state groups with discriminated, render-ready\n * `Field` components rather than a fixed named object.\n *\n * @remarks\n * The state-tax record(s) are created automatically with the employee, so this\n * hook is always in update mode. When the form has no states with submittable\n * answers (e.g. an employee in a no-income-tax state), submit resolves with\n * the existing record list without making a network request.\n *\n * @param props - Hook options.\n * @returns A loading result while data is fetching, or a ready result with\n * form data, fields, status, actions, and error handling.\n * @public\n *\n * @example\n * ```tsx\n * import {\n * useEmployeeStateTaxesForm,\n * SDKFormProvider,\n * type UseEmployeeStateTaxesFormReady,\n * } from '@gusto/embedded-react-sdk'\n *\n * function StateTaxesPage({ employeeId }: { employeeId: string }) {\n * const stateTaxes = useEmployeeStateTaxesForm({ employeeId })\n *\n * if (stateTaxes.isLoading) return <div>Loading...</div>\n *\n * return <StateTaxesFormReady stateTaxes={stateTaxes} />\n * }\n *\n * function StateTaxesFormReady({\n * stateTaxes,\n * }: {\n * stateTaxes: UseEmployeeStateTaxesFormReady\n * }) {\n * const handleSubmit = async () => {\n * const result = await stateTaxes.actions.onSubmit()\n * if (result) console.log('Updated state tax records:', result.data)\n * }\n *\n * return (\n * <SDKFormProvider formHookResult={stateTaxes}>\n * <form\n * onSubmit={e => {\n * e.preventDefault()\n * void handleSubmit()\n * }}\n * >\n * {stateTaxes.form.Fields.map(group => (\n * <section key={group.state}>\n * <h2>{group.state}</h2>\n * {group.questions.map(question => (\n * <question.Field key={question.questionId} />\n * ))}\n * </section>\n * ))}\n * <button type=\"submit\" disabled={stateTaxes.status.isPending}>\n * Save\n * </button>\n * </form>\n * </SDKFormProvider>\n * )\n * }\n * ```\n */\nexport function useEmployeeStateTaxesForm({\n employeeId,\n isAdmin = false,\n validationMode = 'onSubmit',\n shouldFocusError = true,\n}: UseEmployeeStateTaxesFormProps): UseEmployeeStateTaxesFormResult {\n const stateTaxesQuery = useEmployeeTaxSetupGetStateTaxes({ employeeUuid: employeeId })\n\n const employeeStateTaxes = useMemo<EmployeeStateTaxesList[]>(\n () => stateTaxesQuery.data?.employeeStateTaxesList ?? [],\n [stateTaxesQuery.data?.employeeStateTaxesList],\n )\n\n const [schema, metadataConfig] = useMemo(\n () => createEmployeeStateTaxesSchema(employeeStateTaxes, { isAdmin }),\n [employeeStateTaxes, isAdmin],\n )\n\n const fieldsArray = useMemo(\n () => createStateFields(employeeStateTaxes, { isAdmin }),\n [employeeStateTaxes, isAdmin],\n )\n\n const resolvedDefaults = useMemo(\n () => deriveDefaultValues(employeeStateTaxes, isAdmin),\n [employeeStateTaxes, isAdmin],\n )\n\n const formMethods = useForm<EmployeeStateTaxesFormData, unknown, EmployeeStateTaxesFormOutputs>({\n resolver: zodResolver(schema),\n mode: validationMode,\n shouldFocusError,\n defaultValues: resolvedDefaults,\n values: resolvedDefaults,\n resetOptions: { keepDirtyValues: true },\n })\n\n const { mutateAsync: updateStateTaxes, isPending } = useEmployeeTaxSetupUpdateStateTaxesMutation()\n\n const {\n baseSubmitHandler,\n error: submitError,\n setError: setSubmitError,\n } = useBaseSubmit('EmployeeStateTaxesForm')\n\n const errorHandling = composeErrorHandler([stateTaxesQuery], {\n submitError,\n setSubmitError,\n })\n\n const fieldsMetadata = useDeriveFieldsMetadata(\n metadataConfig as EmployeeStateTaxesMetadataConfig,\n formMethods.control,\n ) as FieldsMetadata\n\n const onSubmit = async (): Promise<HookSubmitResult<EmployeeStateTaxesList[]> | undefined> => {\n let submitResult: HookSubmitResult<EmployeeStateTaxesList[]> | undefined\n\n await new Promise<void>(resolve => {\n void formMethods.handleSubmit(\n async data => {\n await baseSubmitHandler(data, async payload => {\n const requestStates = serializeStatesPayload(payload, employeeStateTaxes, isAdmin)\n\n if (requestStates.length === 0) {\n submitResult = { mode: 'update', data: employeeStateTaxes }\n return\n }\n\n const requestBody: EmployeeStateTaxesRequest = { states: requestStates }\n const response = await updateStateTaxes({\n request: { employeeUuid: employeeId, employeeStateTaxesRequest: requestBody },\n })\n\n const updated = response.employeeStateTaxesList\n if (!updated) {\n throw new SDKInternalError('State taxes update did not return an updated record')\n }\n\n submitResult = { mode: 'update', data: updated }\n })\n resolve()\n },\n () => {\n resolve()\n },\n )()\n })\n\n return submitResult\n }\n\n const hookFormInternals = useHookFormInternals(formMethods)\n\n if (stateTaxesQuery.isLoading || !stateTaxesQuery.data?.employeeStateTaxesList) {\n return { isLoading: true as const, errorHandling }\n }\n\n return {\n isLoading: false as const,\n data: { employeeStateTaxes },\n status: { isPending, mode: 'update' as const },\n actions: { onSubmit },\n errorHandling,\n form: {\n Fields: fieldsArray,\n fieldsMetadata,\n hookFormInternals,\n getFormSubmissionValues: createGetFormSubmissionValues(formMethods, schema) as () =>\n Record<string, unknown> | undefined,\n },\n }\n}\n\n// ── Defaults derivation ────────────────────────────────────────────────\n\nfunction deriveDefaultValues(\n employeeStateTaxes: EmployeeStateTaxesList[],\n isAdmin: boolean,\n): EmployeeStateTaxesFormData {\n const states: Record<string, Record<string, unknown>> = {}\n\n for (const stateGroup of employeeStateTaxes) {\n if (!stateGroup.state || !stateGroup.questions) continue\n\n const stateValues: Record<string, unknown> = {}\n for (const question of stateGroup.questions) {\n if (question.isQuestionForAdminOnly && !isAdmin) continue\n const formKey = snakeCaseToCamelCase(question.key)\n const wireValue = question.answers[0]?.value\n stateValues[formKey] = resolveDefaultForQuestion(question, wireValue)\n }\n\n if (Object.keys(stateValues).length > 0) {\n states[stateGroup.state] = stateValues\n }\n }\n\n return { states: states as EmployeeStateTaxesFormData['states'] }\n}\n\nfunction resolveDefaultForQuestion(\n question: EmployeeStateTaxesList['questions'] extends Array<infer Q> | undefined ? Q : never,\n wireValue: string | number | boolean | null | undefined,\n): unknown {\n if (question.key === 'file_new_hire_report') {\n if (wireValue === undefined || wireValue === null) return true\n return wireValue\n }\n\n const variant = getQuestionVariant(question)\n\n switch (variant) {\n case 'date': {\n if (wireValue === undefined || wireValue === null || wireValue === '') return undefined\n if (typeof wireValue === 'string') {\n const trimmed = wireValue.trim()\n if (trimmed === '') return undefined\n const parsed = new Date(trimmed)\n return Number.isNaN(parsed.getTime()) ? undefined : parsed\n }\n return wireValue\n }\n case 'number':\n case 'currency': {\n if (wireValue === undefined || wireValue === null || wireValue === '') return undefined\n const parsed = typeof wireValue === 'number' ? wireValue : Number(wireValue)\n return Number.isNaN(parsed) ? undefined : parsed\n }\n default:\n return wireValue\n }\n}\n\n// ── Submit serialization ───────────────────────────────────────────────\n\ntype SerializedQuestion = {\n key: string\n answers: Array<{\n validFrom: string\n validUpTo: string | null\n value: string | number | boolean\n }>\n}\n\nfunction serializeStatesPayload(\n payload: EmployeeStateTaxesFormOutputs,\n employeeStateTaxes: EmployeeStateTaxesList[],\n isAdmin: boolean,\n): EmployeeStateTaxesRequestState[] {\n const { states: statesPayload } = payload\n if (Object.keys(statesPayload).length === 0) return []\n\n const result: EmployeeStateTaxesRequestState[] = []\n\n for (const state of employeeStateTaxes) {\n const stateName = state.state\n if (!stateName || state.questions === undefined) continue\n\n const serialized: SerializedQuestion[] = []\n for (const question of state.questions) {\n if (question.isQuestionForAdminOnly && !isAdmin) continue\n\n const formValue = (statesPayload[stateName] as Record<string, unknown> | undefined)?.[\n snakeCaseToCamelCase(question.key)\n ]\n\n let serializedValue: string | number | boolean\n if (formValue === undefined || formValue === null) {\n serializedValue = ''\n } else if (typeof formValue === 'number' && Number.isNaN(formValue)) {\n serializedValue = ''\n } else if (formValue instanceof Date) {\n if (Number.isNaN(formValue.getTime())) {\n serializedValue = ''\n } else {\n serializedValue = formValue.toISOString().split('T')[0] ?? ''\n }\n } else {\n serializedValue = formValue as string | number | boolean\n }\n\n serialized.push({\n key: question.key,\n answers: [\n {\n validFrom: question.answers[0]?.validFrom ?? DEFAULT_TAX_VALID_FROM,\n validUpTo: question.answers[0]?.validUpTo ?? null,\n value: serializedValue,\n },\n ],\n })\n }\n\n result.push({ state: stateName, questions: serialized })\n }\n\n return result\n}\n\n/**\n * Static field metadata keyed by full form path (`states.<STATE>.<camelKey>`),\n * with `isRequired` / `isDisabled` and option lists.\n *\n * @public\n */\nexport type EmployeeStateTaxesFieldsMetadata =\n UseEmployeeStateTaxesFormReady['form']['fieldsMetadata']\n\n/**\n * The array of per-state field groups exposed by\n * {@link useEmployeeStateTaxesForm} on `form.Fields`.\n *\n * @public\n */\nexport type EmployeeStateTaxesFormFields = UseEmployeeStateTaxesFormReady['form']['Fields']\n"],"names":["DEFAULT_TAX_VALID_FROM","useEmployeeStateTaxesForm","employeeId","isAdmin","validationMode","shouldFocusError","stateTaxesQuery","useEmployeeTaxSetupGetStateTaxes","employeeStateTaxes","useMemo","schema","metadataConfig","createEmployeeStateTaxesSchema","fieldsArray","createStateFields","resolvedDefaults","deriveDefaultValues","formMethods","useForm","zodResolver","updateStateTaxes","isPending","useEmployeeTaxSetupUpdateStateTaxesMutation","baseSubmitHandler","submitError","setSubmitError","useBaseSubmit","errorHandling","composeErrorHandler","fieldsMetadata","useDeriveFieldsMetadata","onSubmit","submitResult","resolve","data","payload","requestStates","serializeStatesPayload","updated","SDKInternalError","hookFormInternals","useHookFormInternals","createGetFormSubmissionValues","states","stateGroup","stateValues","question","formKey","snakeCaseToCamelCase","wireValue","resolveDefaultForQuestion","getQuestionVariant","trimmed","parsed","statesPayload","result","state","stateName","serialized","formValue","serializedValue"],"mappings":"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"}
1
+ {"version":3,"file":"useEmployeeStateTaxesForm.js","sources":["../../../../../../src/components/Employee/StateTaxes/shared/useEmployeeStateTaxesForm/useEmployeeStateTaxesForm.tsx"],"sourcesContent":["import { useMemo } from 'react'\nimport { useForm } from 'react-hook-form'\nimport type { UseFormProps } from 'react-hook-form'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport type { EmployeeStateTaxesList } from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxeslist'\nimport type {\n EmployeeStateTaxesRequest,\n States as EmployeeStateTaxesRequestState,\n} from '@gusto/embedded-api-v-2025-11-15/models/components/employeestatetaxesrequest'\nimport { useEmployeeTaxSetupGetStateTaxes } from '@gusto/embedded-api-v-2025-11-15/react-query/employeeTaxSetupGetStateTaxes'\nimport { useEmployeeTaxSetupUpdateStateTaxesMutation } from '@gusto/embedded-api-v-2025-11-15/react-query/employeeTaxSetupUpdateStateTaxes'\nimport {\n createEmployeeStateTaxesSchema,\n type EmployeeStateTaxesFormData,\n type EmployeeStateTaxesFormOutputs,\n type EmployeeStateTaxesMetadataConfig,\n} from './employeeStateTaxesSchema'\nimport type { StateTaxFields } from './fields'\nimport { createStateFields } from './fields'\nimport { getQuestionVariant } from './fieldMapping'\nimport { snakeCaseToCamelCase } from '@/helpers/formattedStrings'\nimport { useDeriveFieldsMetadata } from '@/partner-hook-utils/form/useDeriveFieldsMetadata'\nimport { createGetFormSubmissionValues } from '@/partner-hook-utils/form/getFormSubmissionValues'\nimport { useHookFormInternals } from '@/partner-hook-utils/form/useHookFormInternals'\nimport { composeErrorHandler } from '@/partner-hook-utils/composeErrorHandler'\nimport type {\n BaseFormHookReady,\n FieldsMetadata,\n HookLoadingResult,\n HookSubmitResult,\n} from '@/partner-hook-utils/types'\nimport { useBaseSubmit } from '@/components/Base/useBaseSubmit'\nimport { SDKInternalError } from '@/types/sdkError'\n\nconst DEFAULT_TAX_VALID_FROM = '2010-01-01'\n\n/**\n * Options accepted by {@link useEmployeeStateTaxesForm}.\n *\n * @public\n */\nexport interface UseEmployeeStateTaxesFormProps {\n /** The UUID of the employee whose state taxes are being updated. */\n employeeId: string\n /**\n * When `true`, admin-only questions are visible and submitted. When\n * `false`, they are filtered out and the surfaced answer for those\n * questions is preserved unchanged on submit.\n */\n isAdmin?: boolean\n /** When validation runs. Passed through to react-hook-form. Defaults to `'onSubmit'`. */\n validationMode?: UseFormProps['mode']\n /** Auto-focus the first invalid field on submit. Defaults to `true`. Set to `false` when composing with other forms. */\n shouldFocusError?: boolean\n}\n\n/**\n * Ready-state return value of {@link useEmployeeStateTaxesForm} — the\n * `isLoading: false` branch of {@link UseEmployeeStateTaxesFormResult}.\n *\n * @public\n */\nexport interface UseEmployeeStateTaxesFormReady extends BaseFormHookReady<\n FieldsMetadata,\n EmployeeStateTaxesFormData,\n StateTaxFields\n> {\n /** Current per-state tax records returned by the server. */\n data: {\n employeeStateTaxes: EmployeeStateTaxesList[]\n }\n /** Submission status. `mode` is always `'update'` since state-tax records are created with the employee. */\n status: { isPending: boolean; mode: 'update' }\n /** Form actions. */\n actions: {\n /** Validates and submits the form, resolving to the updated records on success or `undefined` when validation blocked the submit. */\n onSubmit: () => Promise<HookSubmitResult<EmployeeStateTaxesList[]> | undefined>\n }\n}\n\n/**\n * Discriminated union returned by {@link useEmployeeStateTaxesForm}. Loading\n * branch carries only `errorHandling`; ready branch carries form data,\n * fields, status, and actions.\n *\n * @public\n */\nexport type UseEmployeeStateTaxesFormResult = HookLoadingResult | UseEmployeeStateTaxesFormReady\n\n/**\n * Headless form hook for updating an employee's state tax withholding answers.\n * The set of questions is driven by the API response per state, so\n * `form.Fields` is an array of state groups with discriminated, render-ready\n * `Field` components rather than a fixed named object.\n *\n * @remarks\n * The state-tax record(s) are created automatically with the employee, so this\n * hook is always in update mode. When the form has no states with submittable\n * answers (e.g. an employee in a no-income-tax state), submit resolves with\n * the existing record list without making a network request.\n *\n * @param props - Hook options.\n * @returns A loading result while data is fetching, or a ready result with\n * form data, fields, status, actions, and error handling.\n * @public\n *\n * @example\n * ```tsx\n * import {\n * useEmployeeStateTaxesForm,\n * SDKFormProvider,\n * type UseEmployeeStateTaxesFormReady,\n * } from '@gusto/embedded-react-sdk'\n *\n * function StateTaxesPage({ employeeId }: { employeeId: string }) {\n * const stateTaxes = useEmployeeStateTaxesForm({ employeeId })\n *\n * if (stateTaxes.isLoading) return <div>Loading...</div>\n *\n * return <StateTaxesFormReady stateTaxes={stateTaxes} />\n * }\n *\n * function StateTaxesFormReady({\n * stateTaxes,\n * }: {\n * stateTaxes: UseEmployeeStateTaxesFormReady\n * }) {\n * const handleSubmit = async () => {\n * const result = await stateTaxes.actions.onSubmit()\n * if (result) console.log('Updated state tax records:', result.data)\n * }\n *\n * return (\n * <SDKFormProvider formHookResult={stateTaxes}>\n * <form\n * onSubmit={e => {\n * e.preventDefault()\n * void handleSubmit()\n * }}\n * >\n * {stateTaxes.form.Fields.map(group => (\n * <section key={group.state}>\n * <h2>{group.state}</h2>\n * {group.questions.map(question => (\n * <question.Field key={question.questionId} />\n * ))}\n * </section>\n * ))}\n * <button type=\"submit\" disabled={stateTaxes.status.isPending}>\n * Save\n * </button>\n * </form>\n * </SDKFormProvider>\n * )\n * }\n * ```\n */\nexport function useEmployeeStateTaxesForm({\n employeeId,\n isAdmin = false,\n validationMode = 'onSubmit',\n shouldFocusError = true,\n}: UseEmployeeStateTaxesFormProps): UseEmployeeStateTaxesFormResult {\n const stateTaxesQuery = useEmployeeTaxSetupGetStateTaxes({ employeeUuid: employeeId })\n\n const employeeStateTaxes = useMemo<EmployeeStateTaxesList[]>(\n () => stateTaxesQuery.data?.employeeStateTaxesList ?? [],\n [stateTaxesQuery.data?.employeeStateTaxesList],\n )\n\n const [schema, metadataConfig] = useMemo(\n () => createEmployeeStateTaxesSchema(employeeStateTaxes, { isAdmin }),\n [employeeStateTaxes, isAdmin],\n )\n\n const fieldsArray = useMemo(\n () => createStateFields(employeeStateTaxes, { isAdmin }),\n [employeeStateTaxes, isAdmin],\n )\n\n const resolvedDefaults = useMemo(\n () => deriveDefaultValues(employeeStateTaxes, isAdmin),\n [employeeStateTaxes, isAdmin],\n )\n\n const formMethods = useForm<EmployeeStateTaxesFormData, unknown, EmployeeStateTaxesFormOutputs>({\n resolver: zodResolver(schema),\n mode: validationMode,\n shouldFocusError,\n defaultValues: resolvedDefaults,\n values: resolvedDefaults,\n resetOptions: { keepDirtyValues: true },\n })\n\n const { mutateAsync: updateStateTaxes, isPending } = useEmployeeTaxSetupUpdateStateTaxesMutation()\n\n const {\n baseSubmitHandler,\n error: submitError,\n setError: setSubmitError,\n } = useBaseSubmit('EmployeeStateTaxesForm')\n\n const errorHandling = composeErrorHandler([stateTaxesQuery], {\n submitError,\n setSubmitError,\n })\n\n const fieldsMetadata = useDeriveFieldsMetadata(\n metadataConfig as EmployeeStateTaxesMetadataConfig,\n formMethods.control,\n ) as FieldsMetadata\n\n const onSubmit = async (): Promise<HookSubmitResult<EmployeeStateTaxesList[]> | undefined> => {\n let submitResult: HookSubmitResult<EmployeeStateTaxesList[]> | undefined\n\n await new Promise<void>(resolve => {\n void formMethods.handleSubmit(\n async data => {\n await baseSubmitHandler(data, async payload => {\n const requestStates = serializeStatesPayload(payload, employeeStateTaxes, isAdmin)\n\n if (requestStates.length === 0) {\n submitResult = { mode: 'update', data: employeeStateTaxes }\n return\n }\n\n const requestBody: EmployeeStateTaxesRequest = { states: requestStates }\n const response = await updateStateTaxes({\n request: { employeeUuid: employeeId, employeeStateTaxesRequest: requestBody },\n })\n\n const updated = response.employeeStateTaxesList\n if (!updated) {\n throw new SDKInternalError('State taxes update did not return an updated record')\n }\n\n submitResult = { mode: 'update', data: updated }\n })\n resolve()\n },\n () => {\n resolve()\n },\n )()\n })\n\n return submitResult\n }\n\n const hookFormInternals = useHookFormInternals(formMethods)\n\n if (stateTaxesQuery.isLoading || !stateTaxesQuery.data?.employeeStateTaxesList) {\n return { isLoading: true as const, errorHandling }\n }\n\n return {\n isLoading: false as const,\n data: { employeeStateTaxes },\n status: { isPending, mode: 'update' as const },\n actions: { onSubmit },\n errorHandling,\n form: {\n Fields: fieldsArray,\n fieldsMetadata,\n hookFormInternals,\n getFormSubmissionValues: createGetFormSubmissionValues(formMethods, schema) as () =>\n Record<string, unknown> | undefined,\n },\n }\n}\n\n// ── Defaults derivation ────────────────────────────────────────────────\n\nfunction deriveDefaultValues(\n employeeStateTaxes: EmployeeStateTaxesList[],\n isAdmin: boolean,\n): EmployeeStateTaxesFormData {\n const states: Record<string, Record<string, unknown>> = {}\n\n for (const stateGroup of employeeStateTaxes) {\n if (!stateGroup.state || !stateGroup.questions) continue\n\n const stateValues: Record<string, unknown> = {}\n for (const question of stateGroup.questions) {\n if (question.isQuestionForAdminOnly && !isAdmin) continue\n const formKey = snakeCaseToCamelCase(question.key)\n const wireValue = question.answers[0]?.value\n stateValues[formKey] = resolveDefaultForQuestion(question, wireValue)\n }\n\n if (Object.keys(stateValues).length > 0) {\n states[stateGroup.state] = stateValues\n }\n }\n\n return { states: states as EmployeeStateTaxesFormData['states'] }\n}\n\nfunction resolveDefaultForQuestion(\n question: EmployeeStateTaxesList['questions'] extends Array<infer Q> | undefined ? Q : never,\n wireValue: string | number | boolean | null | undefined,\n): unknown {\n if (question.key === 'file_new_hire_report') {\n if (wireValue === undefined || wireValue === null) return true\n return wireValue\n }\n\n const variant = getQuestionVariant(question)\n\n switch (variant) {\n case 'date': {\n if (wireValue === undefined || wireValue === null || wireValue === '') return undefined\n if (typeof wireValue === 'string') {\n const trimmed = wireValue.trim()\n if (trimmed === '') return undefined\n const parsed = new Date(trimmed)\n return Number.isNaN(parsed.getTime()) ? undefined : parsed\n }\n return wireValue\n }\n case 'number':\n case 'currency': {\n if (wireValue === undefined || wireValue === null || wireValue === '') return undefined\n const parsed = typeof wireValue === 'number' ? wireValue : Number(wireValue)\n return Number.isNaN(parsed) ? undefined : parsed\n }\n default:\n return wireValue\n }\n}\n\n// ── Submit serialization ───────────────────────────────────────────────\n\ntype SerializedQuestion = {\n key: string\n answers: Array<{\n validFrom: string\n validUpTo: string | null\n value: string | number | boolean\n }>\n}\n\nfunction serializeStatesPayload(\n payload: EmployeeStateTaxesFormOutputs,\n employeeStateTaxes: EmployeeStateTaxesList[],\n isAdmin: boolean,\n): EmployeeStateTaxesRequestState[] {\n const { states: statesPayload } = payload\n if (Object.keys(statesPayload).length === 0) return []\n\n const result: EmployeeStateTaxesRequestState[] = []\n\n for (const state of employeeStateTaxes) {\n const stateName = state.state\n if (!stateName || state.questions === undefined) continue\n\n const serialized: SerializedQuestion[] = []\n for (const question of state.questions) {\n if (question.isQuestionForAdminOnly && !isAdmin) continue\n\n const formValue = (statesPayload[stateName] as Record<string, unknown> | undefined)?.[\n snakeCaseToCamelCase(question.key)\n ]\n\n let serializedValue: string | number | boolean\n if (formValue === undefined || formValue === null) {\n serializedValue = ''\n } else if (typeof formValue === 'number' && Number.isNaN(formValue)) {\n serializedValue = ''\n } else if (formValue instanceof Date) {\n if (Number.isNaN(formValue.getTime())) {\n serializedValue = ''\n } else {\n serializedValue = formValue.toISOString().split('T')[0] ?? ''\n }\n } else {\n serializedValue = formValue as string | number | boolean\n }\n\n serialized.push({\n key: question.key,\n answers: [\n {\n validFrom: question.answers[0]?.validFrom ?? DEFAULT_TAX_VALID_FROM,\n validUpTo: question.answers[0]?.validUpTo ?? null,\n value: serializedValue,\n },\n ],\n })\n }\n\n result.push({ state: stateName, questions: serialized })\n }\n\n return result\n}\n\n/**\n * Static field metadata keyed by full form path (`states.<STATE>.<camelKey>`),\n * with `isRequired` / `isDisabled` and option lists.\n *\n * @public\n */\nexport type EmployeeStateTaxesFieldsMetadata =\n UseEmployeeStateTaxesFormReady['form']['fieldsMetadata']\n\n/**\n * The array of per-state field groups exposed by\n * {@link useEmployeeStateTaxesForm} on `form.Fields`.\n *\n * @public\n */\nexport type EmployeeStateTaxesFormFields = UseEmployeeStateTaxesFormReady['form']['Fields']\n"],"names":["DEFAULT_TAX_VALID_FROM","useEmployeeStateTaxesForm","employeeId","isAdmin","validationMode","shouldFocusError","stateTaxesQuery","useEmployeeTaxSetupGetStateTaxes","employeeStateTaxes","useMemo","schema","metadataConfig","createEmployeeStateTaxesSchema","fieldsArray","createStateFields","resolvedDefaults","deriveDefaultValues","formMethods","useForm","zodResolver","updateStateTaxes","isPending","useEmployeeTaxSetupUpdateStateTaxesMutation","baseSubmitHandler","submitError","setSubmitError","useBaseSubmit","errorHandling","composeErrorHandler","fieldsMetadata","useDeriveFieldsMetadata","onSubmit","submitResult","resolve","data","payload","requestStates","serializeStatesPayload","updated","SDKInternalError","hookFormInternals","useHookFormInternals","createGetFormSubmissionValues","states","stateGroup","stateValues","question","formKey","snakeCaseToCamelCase","wireValue","resolveDefaultForQuestion","getQuestionVariant","trimmed","parsed","statesPayload","result","state","stateName","serialized","formValue","serializedValue"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import { jsx as n, jsxs as x } from "react/jsx-runtime";
2
2
  import { useMachine as h } from "react-robot";
3
- import { Flex as l } from "../Common/Flex/Flex.js";
4
3
  import { FlowContext as u } from "./useFlow.js";
5
4
  import { FlowHeader as v } from "./FlowHeader.js";
5
+ import { Flex as l } from "../Common/Flex/Flex.js";
6
6
  const E = ({
7
7
  onEvent: m,
8
8
  machine: s
@@ -12,7 +12,7 @@ export interface InformationRequestsFlowProps extends Omit<BaseComponentInterfac
12
12
  * Set to `false` when embedding in a parent that renders the alert elsewhere.
13
13
  */
14
14
  withAlert?: boolean;
15
- /** Callback invoked when the flow or its subcomponents emit an event. */
15
+ /** Callback invoked when the flow or its blocks emit an event. */
16
16
  onEvent?: BaseComponentInterface['onEvent'];
17
17
  }
18
18
  /**
@@ -32,10 +32,10 @@ export interface InformationRequestsFlowProps extends Omit<BaseComponentInterfac
32
32
  * | `informationRequest/form/done` | Fired when an information request is successfully submitted | Response from the Submit information request endpoint |
33
33
  * | `informationRequest/form/cancel` | Fired when the user cancels the response form (closes the modal without submitting) | — |
34
34
  *
35
- * Each piece is also exported as a standalone block (see the Sub-components
35
+ * Each piece is also exported as a standalone block (see the Blocks
36
36
  * table) for composing a custom workflow when this orchestration is the wrong
37
37
  * fit. See the
38
- * {@link https://sdk.gusto.com/docs/integration-guide/composition | Composition guide}
38
+ * {@link https://sdk.gusto.com/docs/guides/integration-guide/composition | Composition guide}
39
39
  * for how to recompose these blocks into your own flow.
40
40
  *
41
41
  * @components
@@ -1 +1 @@
1
- {"version":3,"file":"InformationRequests.js","sources":["../../../src/components/InformationRequests/InformationRequests.tsx"],"sourcesContent":["import { createMachine } from 'robot3'\nimport { useMachine } from 'react-robot'\nimport { Suspense, useCallback, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { InformationRequestList } from './InformationRequestList'\nimport { informationRequestsMachine } from './informationRequestsStateMachine'\nimport { type InformationRequestsContextInterface } from './InformationRequestsComponents'\nimport { BaseBoundaries, type BaseComponentInterface } from '@/components/Base'\nimport { Flex } from '@/components/Common'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\nimport { FlowContext } from '@/components/Flow/useFlow'\nimport { useComponentDictionary, useI18n } from '@/i18n'\nimport { informationRequestEvents, type EventType } from '@/shared/constants'\n\ninterface SubmissionAlert {\n id: number\n}\n\ninterface SubmissionAlertState {\n nextAlertId: number\n alerts: SubmissionAlert[]\n}\n\n/**\n * Props for {@link InformationRequestsFlow}.\n *\n * @public\n */\nexport interface InformationRequestsFlowProps extends Omit<\n BaseComponentInterface<'InformationRequests'>,\n 'onEvent'\n> {\n /** The associated company identifier. */\n companyId: string\n /**\n * When `true` (default), the submission success alert is rendered at the top of this component.\n * Set to `false` when embedding in a parent that renders the alert elsewhere.\n */\n withAlert?: boolean\n /** Callback invoked when the flow or its subcomponents emit an event. */\n onEvent?: BaseComponentInterface['onEvent']\n}\n\nconst ALERT_TYPE = 'informationRequestResponded' as const\n\n/**\n * Hub for viewing and responding to outstanding information requests from Gusto.\n *\n * @remarks\n * Renders the list of open and submitted information requests for a company and hosts the response form in a modal.\n * On successful submit, a dismissible success alert appears at the top of the list (when `withAlert` is `true`) and the modal closes.\n *\n * Information requests can also block payroll processing; in that case they are surfaced inline within\n * `Payroll.PayrollBlockerList`, which embeds this flow with `withAlert={false}` so the blocker list owns the alert UX.\n *\n * @events\n * | Event | Description | Data |\n * | ----- | ----------- | ---- |\n * | `informationRequest/respond` | Fired when the user clicks \"Respond\" on a request and the form modal opens | `{ requestId: string }` |\n * | `informationRequest/form/done` | Fired when an information request is successfully submitted | Response from the Submit information request endpoint |\n * | `informationRequest/form/cancel` | Fired when the user cancels the response form (closes the modal without submitting) | — |\n *\n * Each piece is also exported as a standalone block (see the Sub-components\n * table) for composing a custom workflow when this orchestration is the wrong\n * fit. See the\n * {@link https://sdk.gusto.com/docs/integration-guide/composition | Composition guide}\n * for how to recompose these blocks into your own flow.\n *\n * @components\n * - {@link InformationRequestList}\n * - {@link InformationRequestForm}\n *\n * @param props - See {@link InformationRequestsFlowProps}.\n * @returns The information requests flow surface.\n * @public\n *\n * @example\n * ```tsx title=\"App.tsx\"\n * import { InformationRequests } from '@gusto/embedded-react-sdk'\n *\n * function MyApp() {\n * return (\n * <InformationRequests.InformationRequestsFlow\n * companyId=\"a007e1ab-3595-43c2-ab4b-af7a5af2e365\"\n * onEvent={() => {}}\n * />\n * )\n * }\n * ```\n */\nexport function InformationRequestsFlow({\n companyId,\n dictionary,\n withAlert = true,\n onEvent = () => {},\n}: InformationRequestsFlowProps) {\n useComponentDictionary('InformationRequests', dictionary)\n useI18n('InformationRequests')\n const { t } = useTranslation('InformationRequests')\n const { Modal, LoadingSpinner, Alert, Text } = useComponentContext()\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [alertState, setAlertState] = useState<SubmissionAlertState>({\n nextAlertId: 0,\n alerts: [],\n })\n\n const handleDismissAlert = useCallback((alertId: number) => {\n setAlertState(prev => ({\n ...prev,\n alerts: prev.alerts.filter(alert => alert.id !== alertId),\n }))\n }, [])\n\n const addSubmissionAlert = useCallback(() => {\n setAlertState(prev => ({\n nextAlertId: prev.nextAlertId + 1,\n alerts: [{ id: prev.nextAlertId }, ...prev.alerts],\n }))\n }, [])\n\n const informationRequestsMachineInstance = useMemo(\n () =>\n createMachine(\n 'list',\n informationRequestsMachine,\n (): InformationRequestsContextInterface => ({\n component: null,\n companyId,\n onEvent: handleEvent,\n }),\n ),\n [companyId],\n )\n const [current, send] = useMachine(informationRequestsMachineInstance)\n\n function handleEvent(type: EventType, data?: unknown) {\n send({ type, payload: data })\n\n if (type === informationRequestEvents.INFORMATION_REQUEST_RESPOND) {\n setIsModalOpen(true)\n }\n\n if (\n type === informationRequestEvents.INFORMATION_REQUEST_FORM_CANCEL ||\n type === informationRequestEvents.INFORMATION_REQUEST_FORM_DONE\n ) {\n setIsModalOpen(false)\n }\n\n if (type === informationRequestEvents.INFORMATION_REQUEST_FORM_DONE && withAlert) {\n addSubmissionAlert()\n }\n\n onEvent(type, data)\n }\n\n const handleCloseModal = () => {\n setIsModalOpen(false)\n }\n\n const CurrentComponent = current.context.component\n const Footer = CurrentComponent?.Footer || undefined\n\n return (\n <FlowContext.Provider\n value={{\n ...current.context,\n onEvent: handleEvent,\n }}\n >\n <Flex flexDirection=\"column\" gap={32}>\n {withAlert &&\n alertState.alerts.map(alert => (\n <Alert\n key={alert.id}\n status=\"success\"\n label={t(`alerts.${ALERT_TYPE}.title`)}\n onDismiss={() => {\n handleDismissAlert(alert.id)\n }}\n >\n <Text>{t(`alerts.${ALERT_TYPE}.description`)}</Text>\n </Alert>\n ))}\n\n <Suspense fallback={<LoadingSpinner />}>\n <InformationRequestList companyId={companyId} onEvent={handleEvent} />\n </Suspense>\n <Modal\n isOpen={isModalOpen}\n onClose={handleCloseModal}\n footer={\n Footer && (\n <BaseBoundaries>\n <Suspense fallback={<LoadingSpinner size=\"sm\" />}>\n <Footer onEvent={handleEvent} />\n </Suspense>\n </BaseBoundaries>\n )\n }\n >\n {CurrentComponent && <CurrentComponent />}\n </Modal>\n </Flex>\n </FlowContext.Provider>\n )\n}\n"],"names":["ALERT_TYPE","InformationRequestsFlow","companyId","dictionary","withAlert","onEvent","useComponentDictionary","useI18n","t","useTranslation","Modal","LoadingSpinner","Alert","Text","useComponentContext","isModalOpen","setIsModalOpen","useState","alertState","setAlertState","handleDismissAlert","useCallback","alertId","prev","alert","addSubmissionAlert","informationRequestsMachineInstance","useMemo","createMachine","informationRequestsMachine","handleEvent","current","send","useMachine","type","data","informationRequestEvents","handleCloseModal","CurrentComponent","Footer","jsx","FlowContext","jsxs","Flex","Suspense","InformationRequestList","BaseBoundaries"],"mappings":"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"}
1
+ {"version":3,"file":"InformationRequests.js","sources":["../../../src/components/InformationRequests/InformationRequests.tsx"],"sourcesContent":["import { createMachine } from 'robot3'\nimport { useMachine } from 'react-robot'\nimport { Suspense, useCallback, useMemo, useState } from 'react'\nimport { useTranslation } from 'react-i18next'\nimport { InformationRequestList } from './InformationRequestList'\nimport { informationRequestsMachine } from './informationRequestsStateMachine'\nimport { type InformationRequestsContextInterface } from './InformationRequestsComponents'\nimport { BaseBoundaries, type BaseComponentInterface } from '@/components/Base'\nimport { Flex } from '@/components/Common'\nimport { useComponentContext } from '@/contexts/ComponentAdapter/useComponentContext'\nimport { FlowContext } from '@/components/Flow/useFlow'\nimport { useComponentDictionary, useI18n } from '@/i18n'\nimport { informationRequestEvents, type EventType } from '@/shared/constants'\n\ninterface SubmissionAlert {\n id: number\n}\n\ninterface SubmissionAlertState {\n nextAlertId: number\n alerts: SubmissionAlert[]\n}\n\n/**\n * Props for {@link InformationRequestsFlow}.\n *\n * @public\n */\nexport interface InformationRequestsFlowProps extends Omit<\n BaseComponentInterface<'InformationRequests'>,\n 'onEvent'\n> {\n /** The associated company identifier. */\n companyId: string\n /**\n * When `true` (default), the submission success alert is rendered at the top of this component.\n * Set to `false` when embedding in a parent that renders the alert elsewhere.\n */\n withAlert?: boolean\n /** Callback invoked when the flow or its blocks emit an event. */\n onEvent?: BaseComponentInterface['onEvent']\n}\n\nconst ALERT_TYPE = 'informationRequestResponded' as const\n\n/**\n * Hub for viewing and responding to outstanding information requests from Gusto.\n *\n * @remarks\n * Renders the list of open and submitted information requests for a company and hosts the response form in a modal.\n * On successful submit, a dismissible success alert appears at the top of the list (when `withAlert` is `true`) and the modal closes.\n *\n * Information requests can also block payroll processing; in that case they are surfaced inline within\n * `Payroll.PayrollBlockerList`, which embeds this flow with `withAlert={false}` so the blocker list owns the alert UX.\n *\n * @events\n * | Event | Description | Data |\n * | ----- | ----------- | ---- |\n * | `informationRequest/respond` | Fired when the user clicks \"Respond\" on a request and the form modal opens | `{ requestId: string }` |\n * | `informationRequest/form/done` | Fired when an information request is successfully submitted | Response from the Submit information request endpoint |\n * | `informationRequest/form/cancel` | Fired when the user cancels the response form (closes the modal without submitting) | — |\n *\n * Each piece is also exported as a standalone block (see the Blocks\n * table) for composing a custom workflow when this orchestration is the wrong\n * fit. See the\n * {@link https://sdk.gusto.com/docs/guides/integration-guide/composition | Composition guide}\n * for how to recompose these blocks into your own flow.\n *\n * @components\n * - {@link InformationRequestList}\n * - {@link InformationRequestForm}\n *\n * @param props - See {@link InformationRequestsFlowProps}.\n * @returns The information requests flow surface.\n * @public\n *\n * @example\n * ```tsx title=\"App.tsx\"\n * import { InformationRequests } from '@gusto/embedded-react-sdk'\n *\n * function MyApp() {\n * return (\n * <InformationRequests.InformationRequestsFlow\n * companyId=\"a007e1ab-3595-43c2-ab4b-af7a5af2e365\"\n * onEvent={() => {}}\n * />\n * )\n * }\n * ```\n */\nexport function InformationRequestsFlow({\n companyId,\n dictionary,\n withAlert = true,\n onEvent = () => {},\n}: InformationRequestsFlowProps) {\n useComponentDictionary('InformationRequests', dictionary)\n useI18n('InformationRequests')\n const { t } = useTranslation('InformationRequests')\n const { Modal, LoadingSpinner, Alert, Text } = useComponentContext()\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [alertState, setAlertState] = useState<SubmissionAlertState>({\n nextAlertId: 0,\n alerts: [],\n })\n\n const handleDismissAlert = useCallback((alertId: number) => {\n setAlertState(prev => ({\n ...prev,\n alerts: prev.alerts.filter(alert => alert.id !== alertId),\n }))\n }, [])\n\n const addSubmissionAlert = useCallback(() => {\n setAlertState(prev => ({\n nextAlertId: prev.nextAlertId + 1,\n alerts: [{ id: prev.nextAlertId }, ...prev.alerts],\n }))\n }, [])\n\n const informationRequestsMachineInstance = useMemo(\n () =>\n createMachine(\n 'list',\n informationRequestsMachine,\n (): InformationRequestsContextInterface => ({\n component: null,\n companyId,\n onEvent: handleEvent,\n }),\n ),\n [companyId],\n )\n const [current, send] = useMachine(informationRequestsMachineInstance)\n\n function handleEvent(type: EventType, data?: unknown) {\n send({ type, payload: data })\n\n if (type === informationRequestEvents.INFORMATION_REQUEST_RESPOND) {\n setIsModalOpen(true)\n }\n\n if (\n type === informationRequestEvents.INFORMATION_REQUEST_FORM_CANCEL ||\n type === informationRequestEvents.INFORMATION_REQUEST_FORM_DONE\n ) {\n setIsModalOpen(false)\n }\n\n if (type === informationRequestEvents.INFORMATION_REQUEST_FORM_DONE && withAlert) {\n addSubmissionAlert()\n }\n\n onEvent(type, data)\n }\n\n const handleCloseModal = () => {\n setIsModalOpen(false)\n }\n\n const CurrentComponent = current.context.component\n const Footer = CurrentComponent?.Footer || undefined\n\n return (\n <FlowContext.Provider\n value={{\n ...current.context,\n onEvent: handleEvent,\n }}\n >\n <Flex flexDirection=\"column\" gap={32}>\n {withAlert &&\n alertState.alerts.map(alert => (\n <Alert\n key={alert.id}\n status=\"success\"\n label={t(`alerts.${ALERT_TYPE}.title`)}\n onDismiss={() => {\n handleDismissAlert(alert.id)\n }}\n >\n <Text>{t(`alerts.${ALERT_TYPE}.description`)}</Text>\n </Alert>\n ))}\n\n <Suspense fallback={<LoadingSpinner />}>\n <InformationRequestList companyId={companyId} onEvent={handleEvent} />\n </Suspense>\n <Modal\n isOpen={isModalOpen}\n onClose={handleCloseModal}\n footer={\n Footer && (\n <BaseBoundaries>\n <Suspense fallback={<LoadingSpinner size=\"sm\" />}>\n <Footer onEvent={handleEvent} />\n </Suspense>\n </BaseBoundaries>\n )\n }\n >\n {CurrentComponent && <CurrentComponent />}\n </Modal>\n </Flex>\n </FlowContext.Provider>\n )\n}\n"],"names":["ALERT_TYPE","InformationRequestsFlow","companyId","dictionary","withAlert","onEvent","useComponentDictionary","useI18n","t","useTranslation","Modal","LoadingSpinner","Alert","Text","useComponentContext","isModalOpen","setIsModalOpen","useState","alertState","setAlertState","handleDismissAlert","useCallback","alertId","prev","alert","addSubmissionAlert","informationRequestsMachineInstance","useMemo","createMachine","informationRequestsMachine","handleEvent","current","send","useMachine","type","data","informationRequestEvents","handleCloseModal","CurrentComponent","Footer","jsx","FlowContext","jsxs","Flex","Suspense","InformationRequestList","BaseBoundaries"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { useState as M, useRef as y, useMemo as _, useCallback as m, useEffect as b } from "react";
1
+ import { useState as M, useRef as m, useMemo as _, useCallback as y, useEffect as b } from "react";
2
2
  import { usePayrollsPrepareMutation as L } from "@gusto/embedded-api-v-2025-11-15/react-query/payrollsPrepare";
3
3
  import { usePaySchedulesGet as D } from "@gusto/embedded-api-v-2025-11-15/react-query/paySchedulesGet";
4
4
  import { UnprocessableEntityError as T } from "@gusto/embedded-api-v-2025-11-15/models/errors/unprocessableentityerror";
@@ -11,17 +11,19 @@ import "@gusto/embedded-api-v-2025-11-15/models/errors/apierror";
11
11
  import "@gusto/embedded-api-v-2025-11-15/models/errors/gustoembeddederror";
12
12
  import "@gusto/embedded-api-v-2025-11-15/models/errors/sdkvalidationerror";
13
13
  import "@gusto/embedded-api-v-2025-11-15/models/errors/httpclienterrors";
14
+ import "dompurify";
15
+ import "../../contexts/LocaleProvider/useLocale.js";
14
16
  import "../../shared/constants.js";
15
17
  import "../../contexts/ComponentAdapter/useComponentContext.js";
16
18
  import { retryAsync as x } from "../../helpers/retryAsync.js";
17
- const q = 4, v = 1500, B = (e) => e instanceof T ? e.errors.some((r) => r.category === "invalid_operation") : !1, V = ({
19
+ const q = 4, v = 1500, B = (e) => e instanceof T ? e.errors.some((r) => r.category === "invalid_operation") : !1, Z = ({
18
20
  companyId: e,
19
21
  payrollId: r,
20
22
  employeeUuids: a,
21
23
  sortBy: n,
22
24
  onDataReady: l
23
25
  }) => {
24
- const { mutateAsync: c, isPending: p } = L(), [o, f] = M(), t = y(!1), u = y(!1), { baseSubmitHandler: d } = w(), h = _(() => a?.join(",") ?? "", [a]), { data: S, isLoading: E } = D(
26
+ const { mutateAsync: p, isPending: c } = L(), [o, f] = M(), t = m(!1), u = m(!1), { baseSubmitHandler: d } = w(), h = _(() => a?.join(",") ?? "", [a]), { data: S, isLoading: E } = D(
25
27
  {
26
28
  companyId: e,
27
29
  payScheduleId: o?.payPeriod?.payScheduleUuid || ""
@@ -29,8 +31,8 @@ const q = 4, v = 1500, B = (e) => e instanceof T ? e.errors.some((r) => r.catego
29
31
  {
30
32
  enabled: !!o?.payPeriod?.payScheduleUuid
31
33
  }
32
- ), P = m(async () => {
33
- const i = await c({
34
+ ), P = y(async () => {
35
+ const i = await p({
34
36
  request: {
35
37
  companyId: e,
36
38
  payrollId: r,
@@ -41,7 +43,7 @@ const q = 4, v = 1500, B = (e) => e instanceof T ? e.errors.some((r) => r.catego
41
43
  }
42
44
  });
43
45
  f(i.payrollPrepared), i.payrollPrepared && (t.current = !0, l?.(i.payrollPrepared));
44
- }, [e, r, c, h, n, l]), s = m(async () => {
46
+ }, [e, r, p, h, n, l]), s = y(async () => {
45
47
  await d(
46
48
  null,
47
49
  () => x(P, {
@@ -54,7 +56,7 @@ const q = 4, v = 1500, B = (e) => e instanceof T ? e.errors.some((r) => r.catego
54
56
  b(() => {
55
57
  u.current || (u.current = !0, s());
56
58
  }, [s]);
57
- const g = p && !t.current, R = p && t.current, A = g || E;
59
+ const g = c && !t.current, R = c && t.current, A = g || E;
58
60
  return {
59
61
  handlePreparePayroll: s,
60
62
  preparedPayroll: o,
@@ -65,6 +67,6 @@ const q = 4, v = 1500, B = (e) => e instanceof T ? e.errors.some((r) => r.catego
65
67
  };
66
68
  };
67
69
  export {
68
- V as usePreparedPayrollData
70
+ Z as usePreparedPayrollData
69
71
  };
70
72
  //# sourceMappingURL=usePreparedPayrollData.js.map