@thunderid/react 1.3.2 → 1.4.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 (165) hide show
  1. package/dist/ThunderIDReactClient.d.ts +9 -0
  2. package/dist/ThunderIDReactClient.d.ts.map +1 -1
  3. package/dist/ThunderIDReactClient.js +16 -5
  4. package/dist/ThunderIDReactClient.js.map +1 -1
  5. package/dist/cjs/ThunderIDReactClient.cjs +16 -5
  6. package/dist/cjs/ThunderIDReactClient.cjs.map +1 -1
  7. package/dist/cjs/components/presentation/ChangeCredential/BaseChangeCredential.cjs +1 -1
  8. package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs +1 -1
  9. package/dist/cjs/components/presentation/auth/AcceptInvite/BaseAcceptInvite.cjs.map +1 -1
  10. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs +56 -17
  11. package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs.map +1 -1
  12. package/dist/cjs/components/presentation/auth/InviteUser/BaseInviteUser.cjs +21 -5
  13. package/dist/cjs/components/presentation/auth/InviteUser/BaseInviteUser.cjs.map +1 -1
  14. package/dist/cjs/components/presentation/auth/InviteUser/InviteUser.cjs +6 -0
  15. package/dist/cjs/components/presentation/auth/InviteUser/InviteUser.cjs.map +1 -1
  16. package/dist/cjs/components/primitives/AuthFlowSelect/AuthFlowSelect.cjs +21 -0
  17. package/dist/cjs/components/primitives/AuthFlowSelect/AuthFlowSelect.cjs.map +1 -0
  18. package/dist/cjs/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.cjs +32 -0
  19. package/dist/cjs/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.cjs.map +1 -0
  20. package/dist/cjs/components/primitives/CopyableText/CopyableText.cjs +41 -21
  21. package/dist/cjs/components/primitives/CopyableText/CopyableText.cjs.map +1 -1
  22. package/dist/cjs/components/primitives/CopyableText/CopyableText.styles.cjs +5 -2
  23. package/dist/cjs/components/primitives/CopyableText/CopyableText.styles.cjs.map +1 -1
  24. package/dist/cjs/components/primitives/Icons/Copy.cjs +33 -0
  25. package/dist/cjs/components/primitives/Icons/Copy.cjs.map +1 -0
  26. package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs +2 -1
  27. package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs.map +1 -1
  28. package/dist/cjs/components/primitives/Select/ResourceSelect.cjs +104 -0
  29. package/dist/cjs/components/primitives/Select/ResourceSelect.cjs.map +1 -0
  30. package/dist/cjs/components/primitives/Select/Select.cjs +72 -21
  31. package/dist/cjs/components/primitives/Select/Select.cjs.map +1 -1
  32. package/dist/cjs/components/primitives/Select/Select.styles.cjs +19 -3
  33. package/dist/cjs/components/primitives/Select/Select.styles.cjs.map +1 -1
  34. package/dist/cjs/components/primitives/Select/useSelectMessages.cjs +21 -0
  35. package/dist/cjs/components/primitives/Select/useSelectMessages.cjs.map +1 -0
  36. package/dist/cjs/components/primitives/TextField/TextField.cjs +19 -3
  37. package/dist/cjs/components/primitives/TextField/TextField.cjs.map +1 -1
  38. package/dist/cjs/components/primitives/TextField/TextField.styles.cjs +18 -5
  39. package/dist/cjs/components/primitives/TextField/TextField.styles.cjs.map +1 -1
  40. package/dist/cjs/components/primitives/UserSelect/BaseUserSelect.cjs +33 -0
  41. package/dist/cjs/components/primitives/UserSelect/BaseUserSelect.cjs.map +1 -0
  42. package/dist/cjs/components/primitives/UserSelect/UserSelect.cjs +21 -0
  43. package/dist/cjs/components/primitives/UserSelect/UserSelect.cjs.map +1 -0
  44. package/dist/cjs/components/primitives/UserTypeSelect/BaseUserTypeSelect.cjs +31 -0
  45. package/dist/cjs/components/primitives/UserTypeSelect/BaseUserTypeSelect.cjs.map +1 -0
  46. package/dist/cjs/components/primitives/UserTypeSelect/UserTypeSelect.cjs +21 -0
  47. package/dist/cjs/components/primitives/UserTypeSelect/UserTypeSelect.cjs.map +1 -0
  48. package/dist/cjs/hooks/useFetchAuthFlows.cjs +36 -0
  49. package/dist/cjs/hooks/useFetchAuthFlows.cjs.map +1 -0
  50. package/dist/cjs/hooks/useFetchUserTypes.cjs +34 -0
  51. package/dist/cjs/hooks/useFetchUserTypes.cjs.map +1 -0
  52. package/dist/cjs/hooks/useFetchUsers.cjs +35 -0
  53. package/dist/cjs/hooks/useFetchUsers.cjs.map +1 -0
  54. package/dist/cjs/hooks/useInfiniteOptions.cjs +129 -0
  55. package/dist/cjs/hooks/useInfiniteOptions.cjs.map +1 -0
  56. package/dist/cjs/hooks/useManagementEndpoint.cjs.map +1 -1
  57. package/dist/cjs/index.cjs +56 -0
  58. package/dist/cjs/utils/createAuthenticatedFetcher.cjs +1 -0
  59. package/dist/cjs/utils/createAuthenticatedFetcher.cjs.map +1 -1
  60. package/dist/components/presentation/ChangeCredential/BaseChangeCredential.js +1 -1
  61. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.d.ts.map +1 -1
  62. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js +1 -1
  63. package/dist/components/presentation/auth/AcceptInvite/BaseAcceptInvite.js.map +1 -1
  64. package/dist/components/presentation/auth/AuthOptionFactory.d.ts +9 -1
  65. package/dist/components/presentation/auth/AuthOptionFactory.d.ts.map +1 -1
  66. package/dist/components/presentation/auth/AuthOptionFactory.js +56 -17
  67. package/dist/components/presentation/auth/AuthOptionFactory.js.map +1 -1
  68. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.d.ts +18 -2
  69. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.d.ts.map +1 -1
  70. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.js +22 -6
  71. package/dist/components/presentation/auth/InviteUser/BaseInviteUser.js.map +1 -1
  72. package/dist/components/presentation/auth/InviteUser/InviteUser.d.ts +2 -1
  73. package/dist/components/presentation/auth/InviteUser/InviteUser.d.ts.map +1 -1
  74. package/dist/components/presentation/auth/InviteUser/InviteUser.js +6 -0
  75. package/dist/components/presentation/auth/InviteUser/InviteUser.js.map +1 -1
  76. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.d.ts +11 -0
  77. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.d.ts.map +1 -0
  78. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.js +19 -0
  79. package/dist/components/primitives/AuthFlowSelect/AuthFlowSelect.js.map +1 -0
  80. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.d.ts +14 -0
  81. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.d.ts.map +1 -0
  82. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.js +29 -0
  83. package/dist/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.js.map +1 -0
  84. package/dist/components/primitives/CopyableText/CopyableText.d.ts +9 -0
  85. package/dist/components/primitives/CopyableText/CopyableText.d.ts.map +1 -1
  86. package/dist/components/primitives/CopyableText/CopyableText.js +40 -21
  87. package/dist/components/primitives/CopyableText/CopyableText.js.map +1 -1
  88. package/dist/components/primitives/CopyableText/CopyableText.styles.d.ts.map +1 -1
  89. package/dist/components/primitives/CopyableText/CopyableText.styles.js +5 -2
  90. package/dist/components/primitives/CopyableText/CopyableText.styles.js.map +1 -1
  91. package/dist/components/primitives/Icons/Copy.d.ts +7 -0
  92. package/dist/components/primitives/Icons/Copy.d.ts.map +1 -0
  93. package/dist/components/primitives/Icons/Copy.js +31 -0
  94. package/dist/components/primitives/Icons/Copy.js.map +1 -0
  95. package/dist/components/primitives/PasswordField/PasswordField.d.ts +9 -1
  96. package/dist/components/primitives/PasswordField/PasswordField.d.ts.map +1 -1
  97. package/dist/components/primitives/PasswordField/PasswordField.js +2 -1
  98. package/dist/components/primitives/PasswordField/PasswordField.js.map +1 -1
  99. package/dist/components/primitives/Select/ResourceSelect.d.ts +36 -0
  100. package/dist/components/primitives/Select/ResourceSelect.d.ts.map +1 -0
  101. package/dist/components/primitives/Select/ResourceSelect.js +100 -0
  102. package/dist/components/primitives/Select/ResourceSelect.js.map +1 -0
  103. package/dist/components/primitives/Select/Select.d.ts +22 -13
  104. package/dist/components/primitives/Select/Select.d.ts.map +1 -1
  105. package/dist/components/primitives/Select/Select.js +72 -22
  106. package/dist/components/primitives/Select/Select.js.map +1 -1
  107. package/dist/components/primitives/Select/Select.styles.d.ts.map +1 -1
  108. package/dist/components/primitives/Select/Select.styles.js +19 -3
  109. package/dist/components/primitives/Select/Select.styles.js.map +1 -1
  110. package/dist/components/primitives/Select/__tests__/selectTestUtils.d.ts +6 -0
  111. package/dist/components/primitives/Select/__tests__/selectTestUtils.d.ts.map +1 -0
  112. package/dist/components/primitives/Select/useSelectMessages.d.ts +9 -0
  113. package/dist/components/primitives/Select/useSelectMessages.d.ts.map +1 -0
  114. package/dist/components/primitives/Select/useSelectMessages.js +18 -0
  115. package/dist/components/primitives/Select/useSelectMessages.js.map +1 -0
  116. package/dist/components/primitives/TextField/TextField.d.ts +8 -0
  117. package/dist/components/primitives/TextField/TextField.d.ts.map +1 -1
  118. package/dist/components/primitives/TextField/TextField.js +19 -3
  119. package/dist/components/primitives/TextField/TextField.js.map +1 -1
  120. package/dist/components/primitives/TextField/TextField.styles.d.ts +2 -1
  121. package/dist/components/primitives/TextField/TextField.styles.d.ts.map +1 -1
  122. package/dist/components/primitives/TextField/TextField.styles.js +18 -5
  123. package/dist/components/primitives/TextField/TextField.styles.js.map +1 -1
  124. package/dist/components/primitives/UserSelect/BaseUserSelect.d.ts +15 -0
  125. package/dist/components/primitives/UserSelect/BaseUserSelect.d.ts.map +1 -0
  126. package/dist/components/primitives/UserSelect/BaseUserSelect.js +30 -0
  127. package/dist/components/primitives/UserSelect/BaseUserSelect.js.map +1 -0
  128. package/dist/components/primitives/UserSelect/UserSelect.d.ts +11 -0
  129. package/dist/components/primitives/UserSelect/UserSelect.d.ts.map +1 -0
  130. package/dist/components/primitives/UserSelect/UserSelect.js +19 -0
  131. package/dist/components/primitives/UserSelect/UserSelect.js.map +1 -0
  132. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.d.ts +14 -0
  133. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.d.ts.map +1 -0
  134. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.js +28 -0
  135. package/dist/components/primitives/UserTypeSelect/BaseUserTypeSelect.js.map +1 -0
  136. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.d.ts +11 -0
  137. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.d.ts.map +1 -0
  138. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.js +19 -0
  139. package/dist/components/primitives/UserTypeSelect/UserTypeSelect.js.map +1 -0
  140. package/dist/hooks/useFetchAuthFlows.d.ts +9 -0
  141. package/dist/hooks/useFetchAuthFlows.d.ts.map +1 -0
  142. package/dist/hooks/useFetchAuthFlows.js +33 -0
  143. package/dist/hooks/useFetchAuthFlows.js.map +1 -0
  144. package/dist/hooks/useFetchUserTypes.d.ts +8 -0
  145. package/dist/hooks/useFetchUserTypes.d.ts.map +1 -0
  146. package/dist/hooks/useFetchUserTypes.js +31 -0
  147. package/dist/hooks/useFetchUserTypes.js.map +1 -0
  148. package/dist/hooks/useFetchUsers.d.ts +8 -0
  149. package/dist/hooks/useFetchUsers.d.ts.map +1 -0
  150. package/dist/hooks/useFetchUsers.js +32 -0
  151. package/dist/hooks/useFetchUsers.js.map +1 -0
  152. package/dist/hooks/useInfiniteOptions.d.ts +31 -0
  153. package/dist/hooks/useInfiniteOptions.d.ts.map +1 -0
  154. package/dist/hooks/useInfiniteOptions.js +126 -0
  155. package/dist/hooks/useInfiniteOptions.js.map +1 -0
  156. package/dist/hooks/useManagementEndpoint.d.ts +1 -1
  157. package/dist/hooks/useManagementEndpoint.d.ts.map +1 -1
  158. package/dist/hooks/useManagementEndpoint.js.map +1 -1
  159. package/dist/index.d.ts +18 -1
  160. package/dist/index.d.ts.map +1 -1
  161. package/dist/index.js +12 -2
  162. package/dist/utils/createAuthenticatedFetcher.d.ts.map +1 -1
  163. package/dist/utils/createAuthenticatedFetcher.js +1 -0
  164. package/dist/utils/createAuthenticatedFetcher.js.map +1 -1
  165. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"BaseInviteUser.js","names":["BaseInviteUser: FC<BaseInviteUserProps>","useThunderID","useTranslation","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","styles: any","useStyles","challengeTokenRef: any","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","initializationAttemptedRef: any","tempData: any","storageManager: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","components","handleInputChange: any","newErrors: any","handleInputBlur: any","validateForm: any","value: any","handleSubmit: any","validation: any","inputs: any","payload: Record<string, any>","response: any","resetFlow: any","components: any","extractHeadings: any","title: string | undefined","subtitle: string | undefined","title","subtitle","filterHeadings: any","renderComponents: any","componentsWithoutHeadings: any","renderProps: BaseInviteUserRenderProps","CardPrimitive","Spinner","AlertPrimitive","Typography"],"sources":["../../../../../src/components/presentation/auth/InviteUser/BaseInviteUser.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedFlowType,\n FieldError,\n FlowExecutionError,\n FlowMetadataResponse,\n buildValidatorFromRules,\n logger,\n OrganizationUnitListResponse,\n Preferences,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react';\nimport useStyles from './BaseInviteUser.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport useTheme from '../../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {cx} from '../../../../styles/emotion';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../../utils/flowTransformer';\nimport AlertPrimitive from '../../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../../primitives/Card/Card';\nimport Spinner from '../../../primitives/Spinner/Spinner';\nimport Typography from '../../../primitives/Typography/Typography';\nimport {renderInviteUserComponents} from '../AuthOptionFactory';\n\n/**\n * Flow response structure from the backend.\n */\nexport interface InviteUserFlowResponse {\n challengeToken?: string;\n data?: {\n additionalData?: Record<string, any>;\n components?: any[];\n fieldErrors?: FieldError[];\n meta?: {\n components?: any[];\n };\n };\n error?: FlowExecutionError;\n executionId: string;\n flowStatus: 'INCOMPLETE' | 'COMPLETE' | 'ERROR';\n type?: 'VIEW' | 'REDIRECTION';\n}\n\n/**\n * Render props for custom UI rendering of InviteUser.\n */\nexport interface BaseInviteUserRenderProps {\n /**\n * Additional data from the current flow response (e.g. rootOuId, inviteLink).\n */\n additionalData?: Record<string, any>;\n\n /**\n * Flow components from the current step.\n */\n components: any[];\n\n /**\n * API error (if any).\n */\n error?: Error | null;\n\n /**\n * Current flow execution ID.\n */\n executionId?: string;\n\n /**\n * Field validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Current flow execution ID.\n */\n flowExecId?: string;\n\n /**\n * Function to handle input blur.\n */\n handleInputBlur: (name: string) => void;\n\n /**\n * Function to handle input changes.\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission.\n */\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state.\n */\n isLoading: boolean;\n\n /**\n * Whether the form is valid.\n */\n isValid: boolean;\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Reset the flow to invite another user.\n */\n resetFlow: () => void;\n\n /**\n * Subtitle for the current step.\n */\n subtitle?: string;\n\n /**\n * Title for the current step.\n */\n title?: string;\n\n /**\n * Touched fields.\n */\n touched: Record<string, boolean>;\n\n /**\n * Form values for the current step.\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseInviteUser component.\n */\nexport interface BaseInviteUserProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered.\n */\n children?: (props: BaseInviteUserRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Function to fetch child organization units.\n * When provided, enables the OU tree picker for OU_SELECT components.\n */\n fetchOrganizationUnitChildren?: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse>;\n\n /**\n * Whether the SDK is initialized.\n */\n isInitialized?: boolean;\n\n /**\n * Callback when an error occurs.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: InviteUserFlowResponse) => void;\n\n /**\n * Function to initialize the invite user flow.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onInitialize: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Function to submit flow step data.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onSubmit: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Base component for invite user flow.\n * Handles the flow logic for creating a user and generating an invite link.\n *\n * When no children are provided, renders a default UI with:\n * - Loading spinner during initialization\n * - Error alerts for failures\n * - Flow components (user type selection, user details form)\n * - Invite link display with copy functionality\n *\n * Flow steps handled:\n * 1. User type selection (if multiple types available)\n * 2. User details input (username, email)\n * 3. Invite link generation\n */\nconst BaseInviteUser: FC<BaseInviteUserProps> = ({\n onInitialize,\n onSubmit,\n onError,\n onFlowChange,\n className = '',\n children,\n fetchOrganizationUnitChildren,\n isInitialized = true,\n preferences,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: BaseInviteUserProps): ReactElement => {\n const {meta, isInitialized: isSdkInitialized, getStorageManager} = useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n const [isLoading, setIsLoading] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<InviteUserFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n const [formValues, setFormValues] = useState<Record<string, string>>({});\n const [formErrors, setFormErrors] = useState<Record<string, string>>({});\n const [touchedFields, setTouchedFields] = useState<Record<string, boolean>>({});\n const [isFormValid, setIsFormValid] = useState(true);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n /**\n * Project server-side validation errors from the most recent flow response into the\n * local formErrors state so they render alongside client-side errors. First error\n * per field wins, matching the SDK's single-string-per-field render-prop shape.\n */\n useEffect(() => {\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setFormErrors(errors);\n setTouchedFields((prev: Record<string, boolean>) => ({...prev, ...touched}));\n }, [currentFlow]);\n\n const initializationAttemptedRef: any = useRef(false);\n\n /**\n * Restore any challenge token persisted before an OAuth redirect.\n */\n useEffect(() => {\n if (!isSdkInitialized) return;\n\n (async (): Promise<void> => {\n try {\n const storageManager: any = await getStorageManager();\n const tempData: any = await storageManager?.getTemporaryData();\n if (tempData?.challengeToken) {\n challengeTokenRef.current = tempData.challengeToken as string;\n }\n } catch {\n // StorageManager unavailable — continue without persisted token\n }\n })();\n }, [isSdkInitialized]);\n\n /**\n * Updates challengeTokenRef immediately (stale-closure safe) and persists via\n * the provider's StorageManager so the token survives OAuth redirects.\n */\n const setChallengeToken = async (challengeToken: string | null): Promise<void> => {\n challengeTokenRef.current = challengeToken;\n try {\n const storageManager: any = await getStorageManager();\n if (storageManager) {\n if (challengeToken) {\n await storageManager.setTemporaryDataParameter('challengeToken', challengeToken);\n } else {\n await storageManager.removeTemporaryDataParameter('challengeToken');\n }\n }\n } catch {\n logger.warn('Failed to persist challenge token in storage.');\n }\n };\n\n /**\n * Handle error responses and extract meaningful error messages.\n * Uses the transformer's extractErrorMessage function for consistency.\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t, 'components.inviteUser.errors.generic');\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Call the onError callback if provided\n onError?.(error instanceof Error ? error : new Error(errorMessage));\n },\n [t, onError],\n );\n\n /**\n * Normalize flow response to ensure component-driven format.\n * Transforms data.meta.components to data.components.\n */\n const normalizeFlowResponseLocal: any = useCallback(\n (response: InviteUserFlowResponse): InviteUserFlowResponse => {\n if (!response?.data?.meta?.components) {\n return response;\n }\n\n try {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {\n defaultErrorKey: 'components.inviteUser.errors.generic',\n resolveTranslations: false,\n },\n meta,\n );\n\n return {\n ...response,\n data: {\n ...response.data,\n components: components as any,\n },\n };\n } catch {\n // If transformer throws (e.g., error response), return as-is\n return response;\n }\n },\n [t, children],\n );\n\n /**\n * Handle input value changes.\n */\n const handleInputChange: any = useCallback((name: string, value: string) => {\n setFormValues((prev: any) => ({...prev, [name]: value}));\n // Clear error when user starts typing\n setFormErrors((prev: any) => {\n const newErrors: any = {...prev};\n delete newErrors[name];\n return newErrors;\n });\n }, []);\n\n /**\n * Handle input blur.\n */\n const handleInputBlur: any = useCallback((name: string) => {\n setTouchedFields((prev: any) => ({...prev, [name]: true}));\n }, []);\n\n /**\n * Validate required fields based on components.\n */\n const validateForm: any = useCallback(\n (components: any[]): {errors: Record<string, string>; isValid: boolean} => {\n const errors: Record<string, string> = {};\n\n const validateComponents = (comps: any[]): any => {\n comps.forEach((comp: any) => {\n if (\n (comp.type === 'TEXT_INPUT' ||\n comp.type === 'EMAIL_INPUT' ||\n comp.type === 'SELECT' ||\n comp.type === 'PHONE_INPUT' ||\n comp.type === 'OTP_INPUT' ||\n comp.type === 'DATE_INPUT') &&\n comp.ref\n ) {\n const value: any = formValues[comp.ref];\n if (comp.required && (!value || value.trim() === '')) {\n errors[comp.ref] = `${comp.label || comp.ref} is required`;\n } else {\n // Email validation\n if (comp.type === 'EMAIL_INPUT' && value && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n errors[comp.ref] = 'Please enter a valid email address';\n }\n // Evaluate declarative validation rules from meta.components[].validation.\n if (value && !errors[comp.ref]) {\n const ruleValidator = buildValidatorFromRules(comp.validation);\n if (ruleValidator) {\n const message = ruleValidator(value);\n if (message) {\n errors[comp.ref] = t(message);\n }\n }\n }\n }\n }\n if (comp.components && Array.isArray(comp.components)) {\n validateComponents(comp.components);\n }\n });\n };\n\n validateComponents(components);\n\n return {errors, isValid: Object.keys(errors).length === 0};\n },\n [formValues],\n );\n\n /**\n * Handle form submission.\n */\n const handleSubmit: any = useCallback(\n async (component: any, data?: Record<string, any>) => {\n if (!currentFlow) {\n return;\n }\n\n // Validate form before submission\n const components: any = currentFlow.data?.components || [];\n const validation: any = validateForm(components);\n\n if (!validation.isValid) {\n setFormErrors(validation.errors);\n setIsFormValid(false);\n // Mark all fields as touched\n const touched: Record<string, boolean> = {};\n Object.keys(validation.errors).forEach((key: any) => {\n touched[key] = true;\n });\n setTouchedFields((prev: any) => ({...prev, ...touched}));\n return;\n }\n\n setIsLoading(true);\n setApiError(null);\n setIsFormValid(true);\n\n try {\n // Build payload with form values\n const inputs: any = data || formValues;\n\n const payload: Record<string, any> = {\n executionId: currentFlow.executionId,\n inputs,\n verbose: true,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n };\n\n // Add action ID if component has one\n if (component?.id) {\n payload['action'] = component.id;\n }\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Check for error status\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n return;\n }\n\n // Update current flow and reset form for next step\n setCurrentFlow(response);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [currentFlow, formValues, validateForm, onSubmit, onFlowChange, handleError, normalizeFlowResponseLocal],\n );\n\n /**\n * Reset the flow to invite another user.\n */\n const resetFlow: any = useCallback(() => {\n setIsFlowInitialized(false);\n setCurrentFlow(null);\n setApiError(null);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n initializationAttemptedRef.current = false;\n }, []);\n\n /**\n * reset form values, errors, and touched fields to initial state\n */\n const resetForm = useCallback(() => {\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n setApiError(null);\n setIsFormValid(true);\n }, []);\n\n /**\n * Initialize the flow on component mount.\n */\n useEffect(() => {\n if (isInitialized && !isFlowInitialized && !initializationAttemptedRef.current) {\n initializationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsLoading(true);\n setApiError(null);\n\n try {\n const payload: any = {\n flowType: EmbeddedFlowType.UserOnboarding,\n verbose: true,\n };\n\n const rawResponse: any = await onInitialize(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n await setChallengeToken(response.challengeToken ?? null);\n setCurrentFlow(response);\n setIsFlowInitialized(true);\n onFlowChange?.(response);\n\n // Check for immediate error\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n })();\n }\n }, [isInitialized, isFlowInitialized, onInitialize, onFlowChange, handleError, normalizeFlowResponseLocal]);\n\n /**\n * Recalculate form validity whenever form values or components change.\n * This ensures the submit button is enabled/disabled correctly as the user types.\n */\n useEffect(() => {\n if (currentFlow && isFlowInitialized) {\n const components: any = currentFlow.data?.components || [];\n if (components.length > 0) {\n const validation: any = validateForm(components);\n setIsFormValid(validation.isValid);\n }\n }\n }, [formValues, currentFlow, isFlowInitialized, validateForm]);\n\n /**\n * Extract title and subtitle from components.\n */\n const extractHeadings: any = useCallback((components: any[]): {subtitle?: string; title?: string} => {\n let title: string | undefined;\n let subtitle: string | undefined;\n\n components.forEach((comp: any) => {\n if (comp.type === 'TEXT') {\n if (comp.variant === 'HEADING_1' && !title) {\n title = comp.label;\n } else if ((comp.variant === 'HEADING_2' || comp.variant === 'SUBTITLE_1') && !subtitle) {\n subtitle = comp.label;\n }\n }\n });\n\n return {subtitle, title};\n }, []);\n\n /**\n * Filter out heading components for default rendering.\n */\n const filterHeadings: any = useCallback(\n (components: any[]): any[] =>\n components.filter(\n (comp: any) => !(comp.type === 'TEXT' && (comp.variant === 'HEADING_1' || comp.variant === 'HEADING_2')),\n ),\n [],\n );\n\n /**\n * Render form components using the factory.\n */\n const renderComponents: any = useCallback(\n (components: any[]): ReactElement[] =>\n renderInviteUserComponents(\n components,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData: currentFlow?.data?.additionalData,\n fetchOrganizationUnitChildren,\n onInputBlur: handleInputBlur,\n onSubmit: handleSubmit,\n size,\n variant,\n },\n ),\n [\n customRenderers,\n currentFlow?.data?.additionalData,\n fetchOrganizationUnitChildren,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n handleInputChange,\n handleInputBlur,\n handleSubmit,\n size,\n theme,\n variant,\n ],\n );\n\n // Get components from normalized response, with fallback to meta.components\n const components: any = currentFlow?.data?.components || currentFlow?.data?.meta?.components || [];\n const {title, subtitle} = extractHeadings(components);\n const componentsWithoutHeadings: any = filterHeadings(components);\n\n // Render props\n const renderProps: BaseInviteUserRenderProps = {\n additionalData: currentFlow?.data?.additionalData,\n components,\n error: apiError,\n executionId: currentFlow?.executionId,\n fieldErrors: formErrors,\n handleInputBlur,\n handleInputChange,\n handleSubmit,\n isLoading,\n isValid: isFormValid,\n meta,\n resetFlow,\n subtitle,\n title,\n touched: touchedFields,\n values: formValues,\n };\n\n // If children render prop is provided, use it for custom UI\n if (children) {\n return <div className={className}>{children(renderProps)}</div>;\n }\n\n // Default rendering\n\n // Waiting for SDK initialization\n if (!isInitialized) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Loading state during initialization\n if (!isFlowInitialized && isLoading) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Error state during initialization\n if (!currentFlow && apiError) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Title>Error</AlertPrimitive.Title>\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Flow components\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (title || subtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && title && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && subtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {apiError && (\n <div className={(styles as Record<string, string>)['errorContainer']}>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n <div>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0\n ? renderComponents(componentsWithoutHeadings)\n : !isLoading && (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">No form components available</Typography>\n </AlertPrimitive>\n )}\n {isLoading && (\n <div className={(styles as Record<string, string>)['centeredSpinnerContainerSmall']}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\nexport default BaseInviteUser;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BaseInviteUser.js","names":["BaseInviteUser: FC<BaseInviteUserProps>","useThunderID","useTranslation","useTheme","customRenderers: ComponentRendererMap","ComponentRendererContext","styles: any","useStyles","challengeTokenRef: any","responseFieldErrors: FieldError[] | undefined","errors: Record<string, string>","touched: Record<string, boolean>","initializationAttemptedRef: any","tempData: any","storageManager: any","handleError: any","errorMessage: string","normalizeFlowResponseLocal: any","components","handleInputChange: any","newErrors: any","handleInputBlur: any","validateForm: any","value: any","handleSubmit: any","validation: any","inputs: any","payload: Record<string, any>","response: any","resetFlow: any","components: any","extractHeadings: any","title: string | undefined","subtitle: string | undefined","title","subtitle","filterHeadings: any","renderComponents: any","componentsWithoutHeadings: any","renderProps: BaseInviteUserRenderProps","CardPrimitive","Spinner","AlertPrimitive","Typography"],"sources":["../../../../../src/components/presentation/auth/InviteUser/BaseInviteUser.tsx"],"sourcesContent":["// Copyright 2025-2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedFlowType,\n FieldError,\n FlowExecutionError,\n FlowMetadataResponse,\n buildValidatorFromRules,\n FetchAuthFlows,\n FetchUsers,\n FetchUserTypes,\n logger,\n OrganizationUnitListResponse,\n Preferences,\n resolveFlowTemplateLiterals,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback, useContext, useEffect, useRef, useState} from 'react';\nimport useStyles from './BaseInviteUser.styles';\nimport ComponentRendererContext, {\n ComponentRendererMap,\n} from '../../../../contexts/ComponentRenderer/ComponentRendererContext';\nimport useTheme from '../../../../contexts/Theme/useTheme';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\nimport useTranslation from '../../../../hooks/useTranslation';\nimport {cx} from '../../../../styles/emotion';\nimport {normalizeFlowResponse, extractErrorMessage} from '../../../../utils/flowTransformer';\nimport AlertPrimitive from '../../../primitives/Alert/Alert';\n// eslint-disable-next-line import/no-named-as-default\nimport CardPrimitive, {CardProps} from '../../../primitives/Card/Card';\nimport Spinner from '../../../primitives/Spinner/Spinner';\nimport Typography from '../../../primitives/Typography/Typography';\nimport {renderInviteUserComponents} from '../AuthOptionFactory';\n\n/**\n * Flow response structure from the backend.\n */\nexport interface InviteUserFlowResponse {\n challengeToken?: string;\n data?: {\n additionalData?: Record<string, any>;\n components?: any[];\n fieldErrors?: FieldError[];\n meta?: {\n components?: any[];\n };\n };\n error?: FlowExecutionError;\n executionId: string;\n flowStatus: 'INCOMPLETE' | 'COMPLETE' | 'ERROR';\n type?: 'VIEW' | 'REDIRECTION';\n}\n\n/**\n * Render props for custom UI rendering of InviteUser.\n */\nexport interface BaseInviteUserRenderProps {\n /**\n * Additional data from the current flow response (e.g. rootOuId, inviteLink).\n */\n additionalData?: Record<string, any>;\n\n /**\n * Flow components from the current step.\n */\n components: any[];\n\n /**\n * API error (if any).\n */\n error?: Error | null;\n\n /**\n * Current flow execution ID.\n */\n executionId?: string;\n\n /**\n * Field validation errors.\n */\n fieldErrors: Record<string, string>;\n\n /**\n * Current flow execution ID.\n */\n flowExecId?: string;\n\n /**\n * Function to handle input blur.\n */\n handleInputBlur: (name: string) => void;\n\n /**\n * Function to handle input changes.\n */\n handleInputChange: (name: string, value: string) => void;\n\n /**\n * Function to handle form submission.\n */\n handleSubmit: (component: any, data?: Record<string, any>) => Promise<void>;\n\n /**\n * Loading state.\n */\n isLoading: boolean;\n\n /**\n * Whether the form is valid.\n */\n isValid: boolean;\n\n /**\n * Flow metadata returned by the platform (v2 only). `null` while loading or unavailable.\n */\n meta: FlowMetadataResponse | null;\n\n /**\n * Reset the flow to invite another user.\n */\n resetFlow: () => void;\n\n /**\n * Subtitle for the current step.\n */\n subtitle?: string;\n\n /**\n * Title for the current step.\n */\n title?: string;\n\n /**\n * Touched fields.\n */\n touched: Record<string, boolean>;\n\n /**\n * Form values for the current step.\n */\n values: Record<string, string>;\n}\n\n/**\n * Props for the BaseInviteUser component.\n */\nexport interface BaseInviteUserProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered.\n */\n children?: (props: BaseInviteUserRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Function to fetch child organization units.\n * When provided, enables the OU tree picker for OU_SELECT components.\n */\n fetchOrganizationUnitChildren?: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse>;\n\n /**\n * Function to load one page of authentication flows.\n * When provided, enables the flow picker for AUTH_FLOW_SELECT components.\n */\n fetchAuthFlows?: FetchAuthFlows;\n /**\n * Function to load one page of users.\n * When provided, enables the user picker for USER_SELECT components.\n */\n fetchUsers?: FetchUsers;\n /**\n * Function to load one page of user types.\n * When provided, enables the user type picker for USER_TYPE_SELECT components.\n */\n fetchUserTypes?: FetchUserTypes;\n\n /**\n * Whether the SDK is initialized.\n */\n isInitialized?: boolean;\n\n /**\n * Callback when an error occurs. It also receives the errors of failed user, flow and user type picker loads,\n * which the form itself does not show.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: InviteUserFlowResponse) => void;\n\n /**\n * Function to initialize the invite user flow.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onInitialize: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Function to submit flow step data.\n * This should make an authenticated request to the flow/execute endpoint.\n */\n onSubmit: (payload: Record<string, any>) => Promise<InviteUserFlowResponse>;\n\n /**\n * Component-level preferences to override global i18n and theme settings.\n * Preferences are deep-merged with global ones, with component preferences\n * taking precedence. Affects this component and all its descendants.\n */\n preferences?: Preferences;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component.\n */\n variant?: CardProps['variant'];\n}\n\n/**\n * Base component for invite user flow.\n * Handles the flow logic for creating a user and generating an invite link.\n *\n * When no children are provided, renders a default UI with:\n * - Loading spinner during initialization\n * - Error alerts for failures\n * - Flow components (user type selection, user details form)\n * - Invite link display with copy functionality\n *\n * Flow steps handled:\n * 1. User type selection (if multiple types available)\n * 2. User details input (username, email)\n * 3. Invite link generation\n */\nconst BaseInviteUser: FC<BaseInviteUserProps> = ({\n onInitialize,\n onSubmit,\n onError,\n onFlowChange,\n className = '',\n children,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n isInitialized = true,\n preferences,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: BaseInviteUserProps): ReactElement => {\n const {meta, isInitialized: isSdkInitialized, getStorageManager} = useThunderID();\n const {t} = useTranslation(preferences?.i18n);\n const {theme} = useTheme();\n const customRenderers: ComponentRendererMap = useContext(ComponentRendererContext);\n const styles: any = useStyles(theme, theme.vars.colors.text.primary);\n const [isLoading, setIsLoading] = useState(false);\n const [isFlowInitialized, setIsFlowInitialized] = useState(false);\n const [currentFlow, setCurrentFlow] = useState<InviteUserFlowResponse | null>(null);\n const [apiError, setApiError] = useState<Error | null>(null);\n const [formValues, setFormValues] = useState<Record<string, string>>({});\n const [formErrors, setFormErrors] = useState<Record<string, string>>({});\n const [touchedFields, setTouchedFields] = useState<Record<string, boolean>>({});\n const [isFormValid, setIsFormValid] = useState(true);\n const challengeTokenRef: any = useRef<string | null>(null);\n\n /**\n * Project server-side validation errors from the most recent flow response into the\n * local formErrors state so they render alongside client-side errors. First error\n * per field wins, matching the SDK's single-string-per-field render-prop shape.\n */\n useEffect(() => {\n const responseFieldErrors: FieldError[] | undefined = (currentFlow?.data as any)?.fieldErrors;\n if (!responseFieldErrors || responseFieldErrors.length === 0) {\n return;\n }\n const errors: Record<string, string> = {};\n const touched: Record<string, boolean> = {};\n for (const fe of responseFieldErrors) {\n if (!(fe.identifier in errors)) {\n errors[fe.identifier] = fe.message;\n touched[fe.identifier] = true;\n }\n }\n setFormErrors(errors);\n setTouchedFields((prev: Record<string, boolean>) => ({...prev, ...touched}));\n }, [currentFlow]);\n\n const initializationAttemptedRef: any = useRef(false);\n\n /**\n * Restore any challenge token persisted before an OAuth redirect.\n */\n useEffect(() => {\n if (!isSdkInitialized) return;\n\n (async (): Promise<void> => {\n try {\n const storageManager: any = await getStorageManager();\n const tempData: any = await storageManager?.getTemporaryData();\n if (tempData?.challengeToken) {\n challengeTokenRef.current = tempData.challengeToken as string;\n }\n } catch {\n // StorageManager unavailable — continue without persisted token\n }\n })();\n }, [isSdkInitialized]);\n\n /**\n * Updates challengeTokenRef immediately (stale-closure safe) and persists via\n * the provider's StorageManager so the token survives OAuth redirects.\n */\n const setChallengeToken = async (challengeToken: string | null): Promise<void> => {\n challengeTokenRef.current = challengeToken;\n try {\n const storageManager: any = await getStorageManager();\n if (storageManager) {\n if (challengeToken) {\n await storageManager.setTemporaryDataParameter('challengeToken', challengeToken);\n } else {\n await storageManager.removeTemporaryDataParameter('challengeToken');\n }\n }\n } catch {\n logger.warn('Failed to persist challenge token in storage.');\n }\n };\n\n /**\n * Handle error responses and extract meaningful error messages.\n * Uses the transformer's extractErrorMessage function for consistency.\n */\n const handleError: any = useCallback(\n (error: any) => {\n const errorMessage: string = extractErrorMessage(error, t, 'components.inviteUser.errors.generic');\n\n // Set the API error state\n setApiError(error instanceof Error ? error : new Error(errorMessage));\n\n // Call the onError callback if provided\n onError?.(error instanceof Error ? error : new Error(errorMessage));\n },\n [t, onError],\n );\n\n /**\n * Normalize flow response to ensure component-driven format.\n * Transforms data.meta.components to data.components.\n */\n const normalizeFlowResponseLocal: any = useCallback(\n (response: InviteUserFlowResponse): InviteUserFlowResponse => {\n if (!response?.data?.meta?.components) {\n return response;\n }\n\n try {\n const {components} = normalizeFlowResponse(\n response,\n t,\n {\n defaultErrorKey: 'components.inviteUser.errors.generic',\n resolveTranslations: false,\n },\n meta,\n );\n\n return {\n ...response,\n data: {\n ...response.data,\n components: components as any,\n },\n };\n } catch {\n // If transformer throws (e.g., error response), return as-is\n return response;\n }\n },\n [t, children],\n );\n\n /**\n * Handle input value changes.\n */\n const handleInputChange: any = useCallback((name: string, value: string) => {\n setFormValues((prev: any) => ({...prev, [name]: value}));\n // Clear error when user starts typing\n setFormErrors((prev: any) => {\n const newErrors: any = {...prev};\n delete newErrors[name];\n return newErrors;\n });\n }, []);\n\n /**\n * Handle input blur.\n */\n const handleInputBlur: any = useCallback((name: string) => {\n setTouchedFields((prev: any) => ({...prev, [name]: true}));\n }, []);\n\n /**\n * Validate required fields based on components.\n */\n const validateForm: any = useCallback(\n (components: any[]): {errors: Record<string, string>; isValid: boolean} => {\n const errors: Record<string, string> = {};\n\n const validateComponents = (comps: any[]): any => {\n comps.forEach((comp: any) => {\n if (\n (comp.type === 'TEXT_INPUT' ||\n comp.type === 'EMAIL_INPUT' ||\n comp.type === 'SELECT' ||\n comp.type === 'PHONE_INPUT' ||\n comp.type === 'OTP_INPUT' ||\n comp.type === 'DATE_INPUT' ||\n comp.type === 'USER_SELECT' ||\n comp.type === 'AUTH_FLOW_SELECT' ||\n comp.type === 'USER_TYPE_SELECT') &&\n comp.ref\n ) {\n const value: any = formValues[comp.ref];\n if (comp.required && (!value || value.trim() === '')) {\n errors[comp.ref] = `${comp.label || comp.ref} is required`;\n } else {\n // Email validation\n if (comp.type === 'EMAIL_INPUT' && value && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value)) {\n errors[comp.ref] = 'Please enter a valid email address';\n }\n // Evaluate declarative validation rules from meta.components[].validation.\n if (value && !errors[comp.ref]) {\n const ruleValidator = buildValidatorFromRules(comp.validation);\n if (ruleValidator) {\n const message = ruleValidator(value);\n if (message) {\n errors[comp.ref] = t(message);\n }\n }\n }\n }\n }\n if (comp.components && Array.isArray(comp.components)) {\n validateComponents(comp.components);\n }\n });\n };\n\n validateComponents(components);\n\n return {errors, isValid: Object.keys(errors).length === 0};\n },\n [formValues],\n );\n\n /**\n * Handle form submission.\n */\n const handleSubmit: any = useCallback(\n async (component: any, data?: Record<string, any>) => {\n if (!currentFlow) {\n return;\n }\n\n // Validate form before submission\n const components: any = currentFlow.data?.components || [];\n const validation: any = validateForm(components);\n\n if (!validation.isValid) {\n setFormErrors(validation.errors);\n setIsFormValid(false);\n // Mark all fields as touched\n const touched: Record<string, boolean> = {};\n Object.keys(validation.errors).forEach((key: any) => {\n touched[key] = true;\n });\n setTouchedFields((prev: any) => ({...prev, ...touched}));\n return;\n }\n\n setIsLoading(true);\n setApiError(null);\n setIsFormValid(true);\n\n try {\n // Build payload with form values\n const inputs: any = data || formValues;\n\n const payload: Record<string, any> = {\n executionId: currentFlow.executionId,\n inputs,\n verbose: true,\n ...(challengeTokenRef.current ? {challengeToken: challengeTokenRef.current} : {}),\n };\n\n // Add action ID if component has one\n if (component?.id) {\n payload['action'] = component.id;\n }\n\n const rawResponse: any = await onSubmit(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n onFlowChange?.(response);\n\n await setChallengeToken(response.challengeToken ?? null);\n\n // Check for error status\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n return;\n }\n\n // Update current flow and reset form for next step\n setCurrentFlow(response);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n\n // Display error from INCOMPLETE response\n if (response?.error) {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n },\n [currentFlow, formValues, validateForm, onSubmit, onFlowChange, handleError, normalizeFlowResponseLocal],\n );\n\n /**\n * Reset the flow to invite another user.\n */\n const resetFlow: any = useCallback(() => {\n setIsFlowInitialized(false);\n setCurrentFlow(null);\n setApiError(null);\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n initializationAttemptedRef.current = false;\n }, []);\n\n /**\n * reset form values, errors, and touched fields to initial state\n */\n const resetForm = useCallback(() => {\n setFormValues({});\n setFormErrors({});\n setTouchedFields({});\n setApiError(null);\n setIsFormValid(true);\n }, []);\n\n /**\n * Initialize the flow on component mount.\n */\n useEffect(() => {\n if (isInitialized && !isFlowInitialized && !initializationAttemptedRef.current) {\n initializationAttemptedRef.current = true;\n\n (async (): Promise<void> => {\n setIsLoading(true);\n setApiError(null);\n\n try {\n const payload: any = {\n flowType: EmbeddedFlowType.UserOnboarding,\n verbose: true,\n };\n\n const rawResponse: any = await onInitialize(payload);\n const response: any = normalizeFlowResponseLocal(rawResponse);\n await setChallengeToken(response.challengeToken ?? null);\n setCurrentFlow(response);\n setIsFlowInitialized(true);\n onFlowChange?.(response);\n\n // Check for immediate error\n if (response.flowStatus === 'ERROR') {\n handleError(response);\n }\n } catch (err) {\n handleError(err);\n } finally {\n setIsLoading(false);\n }\n })();\n }\n }, [isInitialized, isFlowInitialized, onInitialize, onFlowChange, handleError, normalizeFlowResponseLocal]);\n\n /**\n * Recalculate form validity whenever form values or components change.\n * This ensures the submit button is enabled/disabled correctly as the user types.\n */\n useEffect(() => {\n if (currentFlow && isFlowInitialized) {\n const components: any = currentFlow.data?.components || [];\n if (components.length > 0) {\n const validation: any = validateForm(components);\n setIsFormValid(validation.isValid);\n }\n }\n }, [formValues, currentFlow, isFlowInitialized, validateForm]);\n\n /**\n * Extract title and subtitle from components.\n */\n const extractHeadings: any = useCallback(\n (components: any[]): {subtitle?: string; title?: string} => {\n // The flow writes its texts as translation templates, so resolve them here as the field labels are.\n const resolve = (text: string): string => resolveFlowTemplateLiterals(text, {meta, t});\n let title: string | undefined;\n let subtitle: string | undefined;\n\n components.forEach((comp: any) => {\n if (comp.type === 'TEXT') {\n if (comp.variant === 'HEADING_1' && !title) {\n title = comp.label && resolve(comp.label);\n } else if ((comp.variant === 'HEADING_2' || comp.variant === 'SUBTITLE_1') && !subtitle) {\n subtitle = comp.label && resolve(comp.label);\n }\n }\n });\n\n return {subtitle, title};\n },\n [meta, t],\n );\n\n /**\n * Filter out heading components for default rendering.\n */\n const filterHeadings: any = useCallback(\n (components: any[]): any[] =>\n components.filter(\n (comp: any) => !(comp.type === 'TEXT' && (comp.variant === 'HEADING_1' || comp.variant === 'HEADING_2')),\n ),\n [],\n );\n\n /**\n * Render form components using the factory.\n */\n const renderComponents: any = useCallback(\n (components: any[]): ReactElement[] =>\n renderInviteUserComponents(\n components,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n resetForm,\n handleInputChange,\n {\n _customRenderers: customRenderers,\n _theme: theme,\n additionalData: currentFlow?.data?.additionalData,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n meta,\n onInputBlur: handleInputBlur,\n onPickerError: onError,\n onSubmit: handleSubmit,\n size,\n t,\n variant,\n },\n ),\n [\n customRenderers,\n currentFlow?.data?.additionalData,\n fetchAuthFlows,\n fetchOrganizationUnitChildren,\n fetchUsers,\n fetchUserTypes,\n meta,\n onError,\n t,\n formValues,\n touchedFields,\n formErrors,\n isLoading,\n isFormValid,\n handleInputChange,\n handleInputBlur,\n handleSubmit,\n size,\n theme,\n variant,\n ],\n );\n\n // Get components from normalized response, with fallback to meta.components\n const components: any = currentFlow?.data?.components || currentFlow?.data?.meta?.components || [];\n const {title, subtitle} = extractHeadings(components);\n const componentsWithoutHeadings: any = filterHeadings(components);\n\n // Render props\n const renderProps: BaseInviteUserRenderProps = {\n additionalData: currentFlow?.data?.additionalData,\n components,\n error: apiError,\n executionId: currentFlow?.executionId,\n fieldErrors: formErrors,\n handleInputBlur,\n handleInputChange,\n handleSubmit,\n isLoading,\n isValid: isFormValid,\n meta,\n resetFlow,\n subtitle,\n title,\n touched: touchedFields,\n values: formValues,\n };\n\n // If children render prop is provided, use it for custom UI\n if (children) {\n return <div className={className}>{children(renderProps)}</div>;\n }\n\n // Default rendering\n\n // Waiting for SDK initialization\n if (!isInitialized) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Loading state during initialization\n if (!isFlowInitialized && isLoading) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <div className={(styles as Record<string, string>)['centeredSpinnerContainer']}>\n <Spinner size=\"medium\" />\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Error state during initialization\n if (!currentFlow && apiError) {\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n <CardPrimitive.Content>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Title>Error</AlertPrimitive.Title>\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n }\n\n // Flow components\n return (\n <CardPrimitive className={cx(className, styles.card)} variant={variant}>\n {(showTitle || showSubtitle) && (title || subtitle) && (\n <CardPrimitive.Header className={styles.header}>\n {showTitle && title && (\n <CardPrimitive.Title level={2} className={styles.title}>\n {title}\n </CardPrimitive.Title>\n )}\n {showSubtitle && subtitle && (\n <Typography variant=\"body1\" className={styles.subtitle}>\n {subtitle}\n </Typography>\n )}\n </CardPrimitive.Header>\n )}\n <CardPrimitive.Content>\n {apiError && (\n <div className={(styles as Record<string, string>)['errorContainer']}>\n <AlertPrimitive variant=\"error\">\n <AlertPrimitive.Description>{apiError.message}</AlertPrimitive.Description>\n </AlertPrimitive>\n </div>\n )}\n <div>\n {componentsWithoutHeadings && componentsWithoutHeadings.length > 0\n ? renderComponents(componentsWithoutHeadings)\n : !isLoading && (\n <AlertPrimitive variant=\"warning\">\n <Typography variant=\"body1\">No form components available</Typography>\n </AlertPrimitive>\n )}\n {isLoading && (\n <div className={(styles as Record<string, string>)['centeredSpinnerContainerSmall']}>\n <Spinner size=\"small\" />\n </div>\n )}\n </div>\n </CardPrimitive.Content>\n </CardPrimitive>\n );\n};\n\nexport default BaseInviteUser;\n"],"mappings":"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"}
@@ -18,7 +18,8 @@ export interface InviteUserProps {
18
18
  */
19
19
  className?: string;
20
20
  /**
21
- * Callback when an error occurs.
21
+ * Callback when an error occurs. It also receives the errors of failed user, flow and user type picker loads,
22
+ * which the form itself does not show.
22
23
  */
23
24
  onError?: (error: Error) => void;
24
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"InviteUser.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/InviteUser/InviteUser.tsx"],"names":[],"mappings":"AASA,OAAO,EAAC,EAAE,EAAgB,SAAS,EAAc,MAAM,OAAO,CAAC;AAE/D,OAAuB,EAAC,yBAAyB,EAAE,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AAGnG;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,SAAS,CAAC;IAEvD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAE1D;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,QAAA,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA+FnC,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"InviteUser.d.ts","sourceRoot":"","sources":["../../../../../src/components/presentation/auth/InviteUser/InviteUser.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAC,EAAE,EAAgB,SAAS,EAAc,MAAM,OAAO,CAAC;AAE/D,OAAuB,EAAC,yBAAyB,EAAE,sBAAsB,EAAC,MAAM,kBAAkB,CAAC;AAMnG;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,yBAAyB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,SAAS,CAAC;IAEvD;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;OAEG;IACH,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAE1D;;OAEG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,QAAA,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CAsGnC,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -1,4 +1,7 @@
1
1
  import useThunderID_default from "../../../../contexts/ThunderID/useThunderID.js";
2
+ import useFetchUsers_default from "../../../../hooks/useFetchUsers.js";
3
+ import useFetchAuthFlows_default from "../../../../hooks/useFetchAuthFlows.js";
4
+ import useFetchUserTypes_default from "../../../../hooks/useFetchUserTypes.js";
2
5
  import BaseInviteUser_default from "./BaseInviteUser.js";
3
6
  import { EmbeddedFlowType, getOrganizationUnitChildren, resolveResourceEndpoint } from "@thunderid/browser";
4
7
  import { useCallback } from "react";
@@ -100,6 +103,9 @@ const InviteUser = ({ onError, onFlowChange, className, children, size = "medium
100
103
  organizationUnitId: parentId
101
104
  });
102
105
  }, [baseUrl, getAccessToken]),
106
+ fetchAuthFlows: useFetchAuthFlows_default(),
107
+ fetchUsers: useFetchUsers_default(),
108
+ fetchUserTypes: useFetchUserTypes_default(),
103
109
  isInitialized,
104
110
  size,
105
111
  variant,
@@ -1 +1 @@
1
- {"version":3,"file":"InviteUser.js","names":["InviteUser: FC<InviteUserProps>","useThunderID","flowExecuteUrl: string","BaseInviteUser"],"sources":["../../../../../src/components/presentation/auth/InviteUser/InviteUser.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedFlowType,\n getOrganizationUnitChildren,\n OrganizationUnitListResponse,\n resolveResourceEndpoint,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback} from 'react';\n// eslint-disable-next-line import/no-named-as-default\nimport BaseInviteUser, {BaseInviteUserRenderProps, InviteUserFlowResponse} from './BaseInviteUser';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\n\n/**\n * Render props for InviteUser (re-exported for convenience).\n */\nexport type InviteUserRenderProps = BaseInviteUserRenderProps;\n\n/**\n * Props for the InviteUser component.\n */\nexport interface InviteUserProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered by the SDK.\n */\n children?: (props: InviteUserRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Callback when an error occurs.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: InviteUserFlowResponse) => void;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component card.\n */\n variant?: 'outlined' | 'elevated';\n}\n\n/**\n * InviteUser component for initiating invite user flow.\n *\n * This component is designed for admin users in the thunder-develop app to:\n * 1. Select a user type (if multiple available)\n * 2. Enter user details (username, email)\n * 3. Generate an invite link for the end user\n *\n * The component uses the authenticated ThunderID SDK context to make API calls\n * with the admin's access token (requires 'system' scope).\n *\n * @example\n * ```tsx\n * import { InviteUser } from '@thunderid/react';\n *\n * const InviteUserPage = () => {\n * const [inviteLink, setInviteLink] = useState<string>();\n *\n * return (\n * <InviteUser\n * onInviteLinkGenerated={(link, executionId) => setInviteLink(link)}\n * onError={(error) => console.error(error)}\n * >\n * {({ values, components, isLoading, handleInputChange, handleSubmit, inviteLink, isInviteGenerated }) => (\n * <div>\n * {isInviteGenerated ? (\n * <div>\n * <h2>Invite Link Generated!</h2>\n * <p>{inviteLink}</p>\n * </div>\n * ) : (\n * // Render form based on components\n * )}\n * </div>\n * )}\n * </InviteUser>\n * );\n * };\n * ```\n */\nconst InviteUser: FC<InviteUserProps> = ({\n onError,\n onFlowChange,\n className,\n children,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: InviteUserProps): ReactElement => {\n const {http, baseUrl, endpoints, getAccessToken, isInitialized} = useThunderID();\n\n // The user-onboarding flow runs on the resource server, which may differ from `baseUrl` (the\n // authorization server) in a trusted-issuer setup. Honor the `flowExecute` endpoint override.\n const flowExecuteUrl: string = resolveResourceEndpoint('flowExecute', {endpoints}) ?? `${baseUrl}/flow/execute`;\n\n /**\n * Initialize the invite user flow.\n * Makes an authenticated request to /flow/execute with flowType: USER_ONBOARDING.\n */\n const handleInitialize = async (payload: Record<string, any>): Promise<InviteUserFlowResponse> => {\n const response: any = await http.request({\n data: {\n ...payload,\n flowType: EmbeddedFlowType.UserOnboarding,\n verbose: true,\n },\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n url: flowExecuteUrl,\n } as any);\n\n return response.data as InviteUserFlowResponse;\n };\n\n /**\n * Submit flow step data.\n * Makes an authenticated request to /flow/execute with the step data.\n */\n const handleSubmit = async (payload: Record<string, any>): Promise<InviteUserFlowResponse> => {\n const response: any = await http.request({\n data: {\n ...payload,\n verbose: true,\n },\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n url: flowExecuteUrl,\n } as any);\n\n return response.data as InviteUserFlowResponse;\n };\n\n const fetchOrganizationUnitChildren: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse> = useCallback(\n async (parentId: string, limit: number, offset: number): Promise<OrganizationUnitListResponse> => {\n const accessToken: string = await getAccessToken();\n\n return getOrganizationUnitChildren({\n baseUrl,\n headers: {Authorization: `Bearer ${accessToken}`},\n limit,\n offset,\n organizationUnitId: parentId,\n });\n },\n [baseUrl, getAccessToken],\n );\n\n return (\n <BaseInviteUser\n onInitialize={handleInitialize}\n onSubmit={handleSubmit}\n onError={onError}\n onFlowChange={onFlowChange}\n className={className}\n fetchOrganizationUnitChildren={fetchOrganizationUnitChildren}\n isInitialized={isInitialized}\n size={size}\n variant={variant}\n showTitle={showTitle}\n showSubtitle={showSubtitle}\n >\n {children}\n </BaseInviteUser>\n );\n};\n\nexport default InviteUser;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyGA,MAAMA,cAAmC,EACvC,SACA,cACA,WACA,UACA,OAAO,UACP,UAAU,YACV,YAAY,MACZ,eAAe,WACoB;CACnC,MAAM,EAAC,MAAM,SAAS,WAAW,gBAAgB,kBAAiBC,sBAAc;CAIhF,MAAMC,iBAAyB,wBAAwB,eAAe,EAAC,WAAU,CAAC,IAAI,GAAG,QAAQ;;;;;CAMjG,MAAM,mBAAmB,OAAO,YAAkE;AAehG,UAdsB,MAAM,KAAK,QAAQ;GACvC,MAAM;IACJ,GAAG;IACH,UAAU,iBAAiB;IAC3B,SAAS;IACV;GACD,SAAS;IACP,QAAQ;IACR,gBAAgB;IACjB;GACD,QAAQ;GACR,KAAK;GACN,CAAQ,EAEO;;;;;;CAOlB,MAAM,eAAe,OAAO,YAAkE;AAc5F,UAbsB,MAAM,KAAK,QAAQ;GACvC,MAAM;IACJ,GAAG;IACH,SAAS;IACV;GACD,SAAS;IACP,QAAQ;IACR,gBAAgB;IACjB;GACD,QAAQ;GACR,KAAK;GACN,CAAQ,EAEO;;AAsBlB,QACE,oBAACC;EACC,cAAc;EACd,UAAU;EACD;EACK;EACH;EACX,+BAtByC,YAC3C,OAAO,UAAkB,OAAe,WAA0D;AAGhG,UAAO,4BAA4B;IACjC;IACA,SAAS,EAAC,eAAe,UAJC,MAAM,gBAAgB,IAIC;IACjD;IACA;IACA,oBAAoB;IACrB,CAAC;KAEJ,CAAC,SAAS,eAAe,CAC1B;EAUkB;EACT;EACG;EACE;EACG;EAEb;GACc;;AAIrB,yBAAe"}
1
+ {"version":3,"file":"InviteUser.js","names":["InviteUser: FC<InviteUserProps>","useThunderID","flowExecuteUrl: string","BaseInviteUser","useFetchAuthFlows","useFetchUsers","useFetchUserTypes"],"sources":["../../../../../src/components/presentation/auth/InviteUser/InviteUser.tsx"],"sourcesContent":["// Copyright 2025 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n EmbeddedFlowType,\n FetchAuthFlows,\n FetchUsers,\n FetchUserTypes,\n getOrganizationUnitChildren,\n OrganizationUnitListResponse,\n resolveResourceEndpoint,\n} from '@thunderid/browser';\nimport {FC, ReactElement, ReactNode, useCallback} from 'react';\n// eslint-disable-next-line import/no-named-as-default\nimport BaseInviteUser, {BaseInviteUserRenderProps, InviteUserFlowResponse} from './BaseInviteUser';\nimport useThunderID from '../../../../contexts/ThunderID/useThunderID';\nimport useFetchAuthFlows from '../../../../hooks/useFetchAuthFlows';\nimport useFetchUsers from '../../../../hooks/useFetchUsers';\nimport useFetchUserTypes from '../../../../hooks/useFetchUserTypes';\n\n/**\n * Render props for InviteUser (re-exported for convenience).\n */\nexport type InviteUserRenderProps = BaseInviteUserRenderProps;\n\n/**\n * Props for the InviteUser component.\n */\nexport interface InviteUserProps {\n /**\n * Render props function for custom UI.\n * If not provided, default UI will be rendered by the SDK.\n */\n children?: (props: InviteUserRenderProps) => ReactNode;\n\n /**\n * Custom CSS class name.\n */\n className?: string;\n\n /**\n * Callback when an error occurs. It also receives the errors of failed user, flow and user type picker loads,\n * which the form itself does not show.\n */\n onError?: (error: Error) => void;\n\n /**\n * Callback when the flow state changes.\n */\n onFlowChange?: (response: InviteUserFlowResponse) => void;\n\n /**\n * Whether to show the subtitle.\n */\n showSubtitle?: boolean;\n\n /**\n * Whether to show the title.\n */\n showTitle?: boolean;\n\n /**\n * Size variant for the component.\n */\n size?: 'small' | 'medium' | 'large';\n\n /**\n * Theme variant for the component card.\n */\n variant?: 'outlined' | 'elevated';\n}\n\n/**\n * InviteUser component for initiating invite user flow.\n *\n * This component is designed for admin users in the thunder-develop app to:\n * 1. Select a user type (if multiple available)\n * 2. Enter user details (username, email)\n * 3. Generate an invite link for the end user\n *\n * The component uses the authenticated ThunderID SDK context to make API calls\n * with the admin's access token (requires 'system' scope).\n *\n * @example\n * ```tsx\n * import { InviteUser } from '@thunderid/react';\n *\n * const InviteUserPage = () => {\n * const [inviteLink, setInviteLink] = useState<string>();\n *\n * return (\n * <InviteUser\n * onInviteLinkGenerated={(link, executionId) => setInviteLink(link)}\n * onError={(error) => console.error(error)}\n * >\n * {({ values, components, isLoading, handleInputChange, handleSubmit, inviteLink, isInviteGenerated }) => (\n * <div>\n * {isInviteGenerated ? (\n * <div>\n * <h2>Invite Link Generated!</h2>\n * <p>{inviteLink}</p>\n * </div>\n * ) : (\n * // Render form based on components\n * )}\n * </div>\n * )}\n * </InviteUser>\n * );\n * };\n * ```\n */\nconst InviteUser: FC<InviteUserProps> = ({\n onError,\n onFlowChange,\n className,\n children,\n size = 'medium',\n variant = 'outlined',\n showTitle = true,\n showSubtitle = true,\n}: InviteUserProps): ReactElement => {\n const {http, baseUrl, endpoints, getAccessToken, isInitialized} = useThunderID();\n\n // The user-onboarding flow runs on the resource server, which may differ from `baseUrl` (the\n // authorization server) in a trusted-issuer setup. Honor the `flowExecute` endpoint override.\n const flowExecuteUrl: string = resolveResourceEndpoint('flowExecute', {endpoints}) ?? `${baseUrl}/flow/execute`;\n\n /**\n * Initialize the invite user flow.\n * Makes an authenticated request to /flow/execute with flowType: USER_ONBOARDING.\n */\n const handleInitialize = async (payload: Record<string, any>): Promise<InviteUserFlowResponse> => {\n const response: any = await http.request({\n data: {\n ...payload,\n flowType: EmbeddedFlowType.UserOnboarding,\n verbose: true,\n },\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n url: flowExecuteUrl,\n } as any);\n\n return response.data as InviteUserFlowResponse;\n };\n\n /**\n * Submit flow step data.\n * Makes an authenticated request to /flow/execute with the step data.\n */\n const handleSubmit = async (payload: Record<string, any>): Promise<InviteUserFlowResponse> => {\n const response: any = await http.request({\n data: {\n ...payload,\n verbose: true,\n },\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n url: flowExecuteUrl,\n } as any);\n\n return response.data as InviteUserFlowResponse;\n };\n\n const fetchOrganizationUnitChildren: (\n parentId: string,\n limit: number,\n offset: number,\n ) => Promise<OrganizationUnitListResponse> = useCallback(\n async (parentId: string, limit: number, offset: number): Promise<OrganizationUnitListResponse> => {\n const accessToken: string = await getAccessToken();\n\n return getOrganizationUnitChildren({\n baseUrl,\n headers: {Authorization: `Bearer ${accessToken}`},\n limit,\n offset,\n organizationUnitId: parentId,\n });\n },\n [baseUrl, getAccessToken],\n );\n\n const fetchAuthFlows: FetchAuthFlows = useFetchAuthFlows();\n const fetchUsers: FetchUsers = useFetchUsers();\n const fetchUserTypes: FetchUserTypes = useFetchUserTypes();\n\n return (\n <BaseInviteUser\n onInitialize={handleInitialize}\n onSubmit={handleSubmit}\n onError={onError}\n onFlowChange={onFlowChange}\n className={className}\n fetchOrganizationUnitChildren={fetchOrganizationUnitChildren}\n fetchAuthFlows={fetchAuthFlows}\n fetchUsers={fetchUsers}\n fetchUserTypes={fetchUserTypes}\n isInitialized={isInitialized}\n size={size}\n variant={variant}\n showTitle={showTitle}\n showSubtitle={showSubtitle}\n >\n {children}\n </BaseInviteUser>\n );\n};\n\nexport default InviteUser;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgHA,MAAMA,cAAmC,EACvC,SACA,cACA,WACA,UACA,OAAO,UACP,UAAU,YACV,YAAY,MACZ,eAAe,WACoB;CACnC,MAAM,EAAC,MAAM,SAAS,WAAW,gBAAgB,kBAAiBC,sBAAc;CAIhF,MAAMC,iBAAyB,wBAAwB,eAAe,EAAC,WAAU,CAAC,IAAI,GAAG,QAAQ;;;;;CAMjG,MAAM,mBAAmB,OAAO,YAAkE;AAehG,UAdsB,MAAM,KAAK,QAAQ;GACvC,MAAM;IACJ,GAAG;IACH,UAAU,iBAAiB;IAC3B,SAAS;IACV;GACD,SAAS;IACP,QAAQ;IACR,gBAAgB;IACjB;GACD,QAAQ;GACR,KAAK;GACN,CAAQ,EAEO;;;;;;CAOlB,MAAM,eAAe,OAAO,YAAkE;AAc5F,UAbsB,MAAM,KAAK,QAAQ;GACvC,MAAM;IACJ,GAAG;IACH,SAAS;IACV;GACD,SAAS;IACP,QAAQ;IACR,gBAAgB;IACjB;GACD,QAAQ;GACR,KAAK;GACN,CAAQ,EAEO;;AA0BlB,QACE,oBAACC;EACC,cAAc;EACd,UAAU;EACD;EACK;EACH;EACX,+BA1ByC,YAC3C,OAAO,UAAkB,OAAe,WAA0D;AAGhG,UAAO,4BAA4B;IACjC;IACA,SAAS,EAAC,eAAe,UAJC,MAAM,gBAAgB,IAIC;IACjD;IACA;IACA,oBAAoB;IACrB,CAAC;KAEJ,CAAC,SAAS,eAAe,CAC1B;EAcG,gBAZmCC,2BAAmB;EAatD,YAZ2BC,uBAAe;EAa1C,gBAZmCC,2BAAmB;EAavC;EACT;EACG;EACE;EACG;EAEb;GACc;;AAIrB,yBAAe"}
@@ -0,0 +1,11 @@
1
+ import { FC } from 'react';
2
+ import { BaseAuthFlowSelectProps } from './BaseAuthFlowSelect';
3
+ export type AuthFlowSelectProps = Omit<BaseAuthFlowSelectProps, 'fetchAuthFlows'>;
4
+ /**
5
+ * Authentication-flow picker for signed-in screens. It loads the authentication flows itself with the
6
+ * signed-in user's access token and submits the chosen flow's ID, so it takes no data source. For any
7
+ * other data source use `Select` with `useInfiniteOptions`.
8
+ */
9
+ declare const AuthFlowSelect: FC<AuthFlowSelectProps>;
10
+ export default AuthFlowSelect;
11
+ //# sourceMappingURL=AuthFlowSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthFlowSelect.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/AuthFlowSelect/AuthFlowSelect.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AACzB,OAA2B,EAAC,uBAAuB,EAAC,MAAM,sBAAsB,CAAC;AAGjF,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;AAElF;;;;GAIG;AACH,QAAA,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAE3C,CAAC;AAEF,eAAe,cAAc,CAAC"}
@@ -0,0 +1,19 @@
1
+ import useFetchAuthFlows_default from "../../../hooks/useFetchAuthFlows.js";
2
+ import BaseAuthFlowSelect_default from "./BaseAuthFlowSelect.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ //#region src/components/primitives/AuthFlowSelect/AuthFlowSelect.tsx
6
+ /**
7
+ * Authentication-flow picker for signed-in screens. It loads the authentication flows itself with the
8
+ * signed-in user's access token and submits the chosen flow's ID, so it takes no data source. For any
9
+ * other data source use `Select` with `useInfiniteOptions`.
10
+ */
11
+ const AuthFlowSelect = (props) => /* @__PURE__ */ jsx(BaseAuthFlowSelect_default, {
12
+ ...props,
13
+ fetchAuthFlows: useFetchAuthFlows_default()
14
+ });
15
+ var AuthFlowSelect_default = AuthFlowSelect;
16
+
17
+ //#endregion
18
+ export { AuthFlowSelect_default as default };
19
+ //# sourceMappingURL=AuthFlowSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AuthFlowSelect.js","names":["AuthFlowSelect: FC<AuthFlowSelectProps>","BaseAuthFlowSelect","useFetchAuthFlows"],"sources":["../../../../src/components/primitives/AuthFlowSelect/AuthFlowSelect.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {FC} from 'react';\nimport BaseAuthFlowSelect, {BaseAuthFlowSelectProps} from './BaseAuthFlowSelect';\nimport useFetchAuthFlows from '../../../hooks/useFetchAuthFlows';\n\nexport type AuthFlowSelectProps = Omit<BaseAuthFlowSelectProps, 'fetchAuthFlows'>;\n\n/**\n * Authentication-flow picker for signed-in screens. It loads the authentication flows itself with the\n * signed-in user's access token and submits the chosen flow's ID, so it takes no data source. For any\n * other data source use `Select` with `useInfiniteOptions`.\n */\nconst AuthFlowSelect: FC<AuthFlowSelectProps> = (props: AuthFlowSelectProps) => (\n <BaseAuthFlowSelect {...props} fetchAuthFlows={useFetchAuthFlows()} />\n);\n\nexport default AuthFlowSelect;\n"],"mappings":";;;;;;;;;;AAcA,MAAMA,kBAA2C,UAC/C,oBAACC;CAAmB,GAAI;CAAO,gBAAgBC,2BAAmB;EAAI;AAGxE,6BAAe"}
@@ -0,0 +1,14 @@
1
+ import type { FetchAuthFlows } from '@thunderid/browser';
2
+ import { FC } from 'react';
3
+ import { ResourceSelectProps } from '../Select/ResourceSelect';
4
+ export interface BaseAuthFlowSelectProps extends Omit<ResourceSelectProps, 'bemBlock' | 'defaults' | 'fallbackMessages' | 'fetchPage' | 'mapping' | 'messageKey' | 'resource' | 'type'> {
5
+ fetchAuthFlows?: FetchAuthFlows;
6
+ }
7
+ /**
8
+ * Authentication-flow picker: a `Select` that loads from the given `fetchAuthFlows`, showing each
9
+ * flow by its name and submitting its ID. Building block for {@link AuthFlowSelect}; for a custom
10
+ * data source use `Select` with `useInfiniteOptions`.
11
+ */
12
+ declare const BaseAuthFlowSelect: FC<BaseAuthFlowSelectProps>;
13
+ export default BaseAuthFlowSelect;
14
+ //# sourceMappingURL=BaseAuthFlowSelect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseAuthFlowSelect.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,cAAc,EAAuB,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AACzB,OAAuB,EAAC,mBAAmB,EAAC,MAAM,0BAA0B,CAAC;AAE7E,MAAM,WAAW,uBACf,SAAQ,IAAI,CACV,mBAAmB,EACnB,UAAU,GAAG,UAAU,GAAG,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAC5G;IACD,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAID;;;;GAIG;AACH,QAAA,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAcnD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import ResourceSelect_default from "../Select/ResourceSelect.js";
2
+ import { AuthFlowSelectConstants, EmbeddedFlowComponentType } from "@thunderid/browser";
3
+ import { jsx } from "react/jsx-runtime";
4
+
5
+ //#region src/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.tsx
6
+ const AUTH_FLOW_DEFAULTS = { labelAttributes: AuthFlowSelectConstants.LABEL_ATTRIBUTES };
7
+ /**
8
+ * Authentication-flow picker: a `Select` that loads from the given `fetchAuthFlows`, showing each
9
+ * flow by its name and submitting its ID. Building block for {@link AuthFlowSelect}; for a custom
10
+ * data source use `Select` with `useInfiniteOptions`.
11
+ */
12
+ const BaseAuthFlowSelect = ({ fetchAuthFlows,...rest }) => /* @__PURE__ */ jsx(ResourceSelect_default, {
13
+ ...rest,
14
+ bemBlock: "auth-flow-select",
15
+ defaults: AUTH_FLOW_DEFAULTS,
16
+ fallbackMessages: {
17
+ ariaLabel: "Select a login flow",
18
+ empty: "No login flows found."
19
+ },
20
+ fetchPage: fetchAuthFlows,
21
+ messageKey: "auth_flow_select",
22
+ resource: "auth flows",
23
+ type: EmbeddedFlowComponentType.AuthFlowSelect
24
+ });
25
+ var BaseAuthFlowSelect_default = BaseAuthFlowSelect;
26
+
27
+ //#endregion
28
+ export { BaseAuthFlowSelect_default as default };
29
+ //# sourceMappingURL=BaseAuthFlowSelect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BaseAuthFlowSelect.js","names":["AUTH_FLOW_DEFAULTS: SelectOptionDefaults","BaseAuthFlowSelect: FC<BaseAuthFlowSelectProps>","ResourceSelect"],"sources":["../../../../src/components/primitives/AuthFlowSelect/BaseAuthFlowSelect.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {AuthFlowSelectConstants, EmbeddedFlowComponentType} from '@thunderid/browser';\nimport type {FetchAuthFlows, SelectOptionDefaults} from '@thunderid/browser';\nimport {FC} from 'react';\nimport ResourceSelect, {ResourceSelectProps} from '../Select/ResourceSelect';\n\nexport interface BaseAuthFlowSelectProps\n extends Omit<\n ResourceSelectProps,\n 'bemBlock' | 'defaults' | 'fallbackMessages' | 'fetchPage' | 'mapping' | 'messageKey' | 'resource' | 'type'\n > {\n fetchAuthFlows?: FetchAuthFlows;\n}\n\nconst AUTH_FLOW_DEFAULTS: SelectOptionDefaults = {labelAttributes: AuthFlowSelectConstants.LABEL_ATTRIBUTES};\n\n/**\n * Authentication-flow picker: a `Select` that loads from the given `fetchAuthFlows`, showing each\n * flow by its name and submitting its ID. Building block for {@link AuthFlowSelect}; for a custom\n * data source use `Select` with `useInfiniteOptions`.\n */\nconst BaseAuthFlowSelect: FC<BaseAuthFlowSelectProps> = ({fetchAuthFlows, ...rest}: BaseAuthFlowSelectProps) => (\n <ResourceSelect\n {...rest}\n bemBlock=\"auth-flow-select\"\n defaults={AUTH_FLOW_DEFAULTS}\n fallbackMessages={{\n ariaLabel: 'Select a login flow',\n empty: 'No login flows found.',\n }}\n fetchPage={fetchAuthFlows}\n messageKey=\"auth_flow_select\"\n resource=\"auth flows\"\n type={EmbeddedFlowComponentType.AuthFlowSelect}\n />\n);\n\nexport default BaseAuthFlowSelect;\n"],"mappings":";;;;;AAgBA,MAAMA,qBAA2C,EAAC,iBAAiB,wBAAwB,kBAAiB;;;;;;AAO5G,MAAMC,sBAAmD,EAAC,eAAgB,GAAG,WAC3E,oBAACC;CACC,GAAI;CACJ,UAAS;CACT,UAAU;CACV,kBAAkB;EAChB,WAAW;EACX,OAAO;EACR;CACD,WAAW;CACX,YAAW;CACX,UAAS;CACT,MAAM,0BAA0B;EAChC;AAGJ,iCAAe"}
@@ -4,6 +4,11 @@ export interface CopyableTextProps {
4
4
  * Optional label displayed above the value box.
5
5
  */
6
6
  label?: string;
7
+ /**
8
+ * Hides the value in a read-only password field until the user chooses to show it, as for a secret. Copying always
9
+ * copies the real value.
10
+ */
11
+ masked?: boolean;
7
12
  /**
8
13
  * The text value to display and copy.
9
14
  */
@@ -14,6 +19,10 @@ export interface CopyableTextProps {
14
19
  * the clipboard. When the button is clicked, it attempts to copy the value using the Clipboard API, and
15
20
  * falls back to a textarea method if the API is not supported.
16
21
  * After copying, it shows a "Copied!" message for 3 seconds before resetting.
22
+ *
23
+ * The copy control is an icon button inside the box in both layouts. With `masked`, the value sits in a read-only
24
+ * password field with the same show and hide control as `PasswordField`. A browser does not copy out of a password
25
+ * field, which is why copying is a button of its own.
17
26
  */
18
27
  declare const CopyableText: FC<CopyableTextProps>;
19
28
  export default CopyableText;
@@ -1 +1 @@
1
- {"version":3,"file":"CopyableText.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/CopyableText/CopyableText.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAC,EAAE,EAAsC,MAAM,OAAO,CAAC;AAM9D,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,QAAA,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAuCvC,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"CopyableText.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/CopyableText/CopyableText.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAC,EAAE,EAAsC,MAAM,OAAO,CAAC;AAS9D,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;;;;;;GASG;AACH,QAAA,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAqDvC,CAAC;AAEF,eAAe,YAAY,CAAC"}
@@ -1,55 +1,74 @@
1
1
  import useTheme_default from "../../../contexts/Theme/useTheme.js";
2
2
  import useTranslation_default from "../../../hooks/useTranslation.js";
3
3
  import Button_default from "../Button/Button.js";
4
+ import PasswordField_default from "../PasswordField/PasswordField.js";
4
5
  import CopyableText_styles_default from "./CopyableText.styles.js";
6
+ import Check_default from "../Icons/Check.js";
7
+ import Copy_default from "../Icons/Copy.js";
8
+ import { copyTextToClipboard } from "@thunderid/browser";
5
9
  import { useCallback, useState } from "react";
6
10
  import { jsx, jsxs } from "react/jsx-runtime";
7
11
 
8
12
  //#region src/components/primitives/CopyableText/CopyableText.tsx
13
+ const ignoreChange = () => void 0;
9
14
  /**
10
15
  * A React component that displays a text value with an optional label and a button to copy the value to
11
16
  * the clipboard. When the button is clicked, it attempts to copy the value using the Clipboard API, and
12
17
  * falls back to a textarea method if the API is not supported.
13
18
  * After copying, it shows a "Copied!" message for 3 seconds before resetting.
19
+ *
20
+ * The copy control is an icon button inside the box in both layouts. With `masked`, the value sits in a read-only
21
+ * password field with the same show and hide control as `PasswordField`. A browser does not copy out of a password
22
+ * field, which is why copying is a button of its own.
14
23
  */
15
- const CopyableText = ({ label, value }) => {
24
+ const CopyableText = ({ label, masked = false, value }) => {
16
25
  const { theme } = useTheme_default();
17
26
  const styles = CopyableText_styles_default(theme);
18
27
  const { t } = useTranslation_default();
19
28
  const [copied, setCopied] = useState(false);
20
29
  const handleCopy = useCallback(async () => {
21
- try {
22
- await navigator.clipboard.writeText(value);
23
- } catch {
24
- const textArea = document.createElement("textarea");
25
- textArea.value = value;
26
- document.body.appendChild(textArea);
27
- textArea.select();
28
- document.execCommand("copy");
29
- document.body.removeChild(textArea);
30
- }
30
+ await copyTextToClipboard(value);
31
31
  setCopied(true);
32
32
  setTimeout(() => setCopied(false), 3e3);
33
33
  }, [value]);
34
+ const copyLabel = copied ? t("elements.display.copyable_text.copied") : t("elements.display.copyable_text.copy");
35
+ const copyButton = /* @__PURE__ */ jsx(Button_default, {
36
+ variant: "icon",
37
+ size: "small",
38
+ className: styles["copyButton"],
39
+ "aria-label": copyLabel,
40
+ title: copyLabel,
41
+ onClick: () => {
42
+ handleCopy().catch(() => void 0);
43
+ },
44
+ children: copied ? /* @__PURE__ */ jsx(Check_default, {
45
+ width: 16,
46
+ height: 16
47
+ }) : /* @__PURE__ */ jsx(Copy_default, {
48
+ width: 16,
49
+ height: 16
50
+ })
51
+ });
34
52
  return /* @__PURE__ */ jsxs("div", {
35
53
  className: styles["container"],
36
54
  children: [label && /* @__PURE__ */ jsx("span", {
37
55
  className: styles["label"],
38
56
  children: label
39
- }), /* @__PURE__ */ jsxs("div", {
57
+ }), masked ? /* @__PURE__ */ jsx(PasswordField_default, {
58
+ "aria-label": label,
59
+ autoComplete: "off",
60
+ endAdornment: copyButton,
61
+ hideLabel: t("elements.display.copyable_text.hide"),
62
+ onChange: ignoreChange,
63
+ readOnly: true,
64
+ showLabel: t("elements.display.copyable_text.show"),
65
+ value
66
+ }) : /* @__PURE__ */ jsxs("div", {
40
67
  className: styles["valueBox"],
41
68
  children: [/* @__PURE__ */ jsx("span", {
42
69
  className: styles["valueText"],
43
70
  children: value
44
- }), /* @__PURE__ */ jsx(Button_default, {
45
- variant: "outline",
46
- size: "small",
47
- className: styles["copyButton"],
48
- onClick: () => {
49
- handleCopy().catch(() => void 0);
50
- },
51
- children: copied ? t("elements.display.copyable_text.copied") : t("elements.display.copyable_text.copy")
52
- })]
71
+ }), copyButton]
53
72
  })]
54
73
  });
55
74
  };
@@ -1 +1 @@
1
- {"version":3,"file":"CopyableText.js","names":["CopyableText: FC<CopyableTextProps>","useTheme","styles: Record<string, string>","useStyles","useTranslation","handleCopy: ReturnType<typeof useCallback>","textArea: HTMLTextAreaElement","Button"],"sources":["../../../../src/components/primitives/CopyableText/CopyableText.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {FC, ReactElement, useCallback, useState} from 'react';\nimport useStyles from './CopyableText.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useTranslation from '../../../hooks/useTranslation';\nimport Button from '../Button/Button';\n\nexport interface CopyableTextProps {\n /**\n * Optional label displayed above the value box.\n */\n label?: string;\n /**\n * The text value to display and copy.\n */\n value: string;\n}\n\n/**\n * A React component that displays a text value with an optional label and a button to copy the value to\n * the clipboard. When the button is clicked, it attempts to copy the value using the Clipboard API, and\n * falls back to a textarea method if the API is not supported.\n * After copying, it shows a \"Copied!\" message for 3 seconds before resetting.\n */\nconst CopyableText: FC<CopyableTextProps> = ({label, value}: CopyableTextProps): ReactElement => {\n const {theme} = useTheme();\n const styles: Record<string, string> = useStyles(theme);\n const {t} = useTranslation();\n const [copied, setCopied] = useState(false);\n\n const handleCopy: ReturnType<typeof useCallback> = useCallback(async (): Promise<void> => {\n try {\n await navigator.clipboard.writeText(value);\n } catch {\n const textArea: HTMLTextAreaElement = document.createElement('textarea');\n textArea.value = value;\n document.body.appendChild(textArea);\n textArea.select();\n document.execCommand('copy');\n document.body.removeChild(textArea);\n }\n setCopied(true);\n setTimeout(() => setCopied(false), 3000);\n }, [value]);\n\n return (\n <div className={styles['container']}>\n {label && <span className={styles['label']}>{label}</span>}\n <div className={styles['valueBox']}>\n <span className={styles['valueText']}>{value}</span>\n <Button\n variant=\"outline\"\n size=\"small\"\n className={styles['copyButton']}\n onClick={() => {\n handleCopy().catch(() => undefined);\n }}\n >\n {copied ? t('elements.display.copyable_text.copied') : t('elements.display.copyable_text.copy')}\n </Button>\n </div>\n </div>\n );\n};\n\nexport default CopyableText;\n"],"mappings":";;;;;;;;;;;;;;AA0BA,MAAMA,gBAAuC,EAAC,OAAO,YAA4C;CAC/F,MAAM,EAAC,UAASC,kBAAU;CAC1B,MAAMC,SAAiCC,4BAAU,MAAM;CACvD,MAAM,EAAC,MAAKC,wBAAgB;CAC5B,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;CAE3C,MAAMC,aAA6C,YAAY,YAA2B;AACxF,MAAI;AACF,SAAM,UAAU,UAAU,UAAU,MAAM;UACpC;GACN,MAAMC,WAAgC,SAAS,cAAc,WAAW;AACxE,YAAS,QAAQ;AACjB,YAAS,KAAK,YAAY,SAAS;AACnC,YAAS,QAAQ;AACjB,YAAS,YAAY,OAAO;AAC5B,YAAS,KAAK,YAAY,SAAS;;AAErC,YAAU,KAAK;AACf,mBAAiB,UAAU,MAAM,EAAE,IAAK;IACvC,CAAC,MAAM,CAAC;AAEX,QACE,qBAAC;EAAI,WAAW,OAAO;aACpB,SAAS,oBAAC;GAAK,WAAW,OAAO;aAAW;IAAa,EAC1D,qBAAC;GAAI,WAAW,OAAO;cACrB,oBAAC;IAAK,WAAW,OAAO;cAAe;KAAa,EACpD,oBAACC;IACC,SAAQ;IACR,MAAK;IACL,WAAW,OAAO;IAClB,eAAe;AACb,iBAAY,CAAC,YAAY,OAAU;;cAGpC,SAAS,EAAE,wCAAwC,GAAG,EAAE,sCAAsC;KACxF;IACL;GACF;;AAIV,2BAAe"}
1
+ {"version":3,"file":"CopyableText.js","names":["CopyableText: FC<CopyableTextProps>","useTheme","styles: Record<string, string>","useStyles","useTranslation","handleCopy: ReturnType<typeof useCallback>","copyLabel: string","copyButton: ReactElement","Button","Check","Copy","PasswordField"],"sources":["../../../../src/components/primitives/CopyableText/CopyableText.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {copyTextToClipboard} from '@thunderid/browser';\nimport {FC, ReactElement, useCallback, useState} from 'react';\nimport useStyles from './CopyableText.styles';\nimport useTheme from '../../../contexts/Theme/useTheme';\nimport useTranslation from '../../../hooks/useTranslation';\nimport Button from '../Button/Button';\nimport Check from '../Icons/Check';\nimport Copy from '../Icons/Copy';\nimport PasswordField from '../PasswordField/PasswordField';\n\nexport interface CopyableTextProps {\n /**\n * Optional label displayed above the value box.\n */\n label?: string;\n /**\n * Hides the value in a read-only password field until the user chooses to show it, as for a secret. Copying always\n * copies the real value.\n */\n masked?: boolean;\n /**\n * The text value to display and copy.\n */\n value: string;\n}\n\nconst ignoreChange = (): void => undefined;\n\n/**\n * A React component that displays a text value with an optional label and a button to copy the value to\n * the clipboard. When the button is clicked, it attempts to copy the value using the Clipboard API, and\n * falls back to a textarea method if the API is not supported.\n * After copying, it shows a \"Copied!\" message for 3 seconds before resetting.\n *\n * The copy control is an icon button inside the box in both layouts. With `masked`, the value sits in a read-only\n * password field with the same show and hide control as `PasswordField`. A browser does not copy out of a password\n * field, which is why copying is a button of its own.\n */\nconst CopyableText: FC<CopyableTextProps> = ({label, masked = false, value}: CopyableTextProps): ReactElement => {\n const {theme} = useTheme();\n const styles: Record<string, string> = useStyles(theme);\n const {t} = useTranslation();\n const [copied, setCopied] = useState(false);\n\n const handleCopy: ReturnType<typeof useCallback> = useCallback(async (): Promise<void> => {\n await copyTextToClipboard(value);\n setCopied(true);\n setTimeout(() => setCopied(false), 3000);\n }, [value]);\n\n const copyLabel: string = copied\n ? t('elements.display.copyable_text.copied')\n : t('elements.display.copyable_text.copy');\n\n const copyButton: ReactElement = (\n <Button\n variant=\"icon\"\n size=\"small\"\n className={styles['copyButton']}\n aria-label={copyLabel}\n title={copyLabel}\n onClick={() => {\n handleCopy().catch(() => undefined);\n }}\n >\n {copied ? <Check width={16} height={16} /> : <Copy width={16} height={16} />}\n </Button>\n );\n\n return (\n <div className={styles['container']}>\n {label && <span className={styles['label']}>{label}</span>}\n {masked ? (\n <PasswordField\n aria-label={label}\n autoComplete=\"off\"\n endAdornment={copyButton}\n hideLabel={t('elements.display.copyable_text.hide')}\n onChange={ignoreChange}\n readOnly\n showLabel={t('elements.display.copyable_text.show')}\n value={value}\n />\n ) : (\n <div className={styles['valueBox']}>\n <span className={styles['valueText']}>{value}</span>\n {copyButton}\n </div>\n )}\n </div>\n );\n};\n\nexport default CopyableText;\n"],"mappings":";;;;;;;;;;;;AA6BA,MAAM,qBAA2B;;;;;;;;;;;AAYjC,MAAMA,gBAAuC,EAAC,OAAO,SAAS,OAAO,YAA4C;CAC/G,MAAM,EAAC,UAASC,kBAAU;CAC1B,MAAMC,SAAiCC,4BAAU,MAAM;CACvD,MAAM,EAAC,MAAKC,wBAAgB;CAC5B,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;CAE3C,MAAMC,aAA6C,YAAY,YAA2B;AACxF,QAAM,oBAAoB,MAAM;AAChC,YAAU,KAAK;AACf,mBAAiB,UAAU,MAAM,EAAE,IAAK;IACvC,CAAC,MAAM,CAAC;CAEX,MAAMC,YAAoB,SACtB,EAAE,wCAAwC,GAC1C,EAAE,sCAAsC;CAE5C,MAAMC,aACJ,oBAACC;EACC,SAAQ;EACR,MAAK;EACL,WAAW,OAAO;EAClB,cAAY;EACZ,OAAO;EACP,eAAe;AACb,eAAY,CAAC,YAAY,OAAU;;YAGpC,SAAS,oBAACC;GAAM,OAAO;GAAI,QAAQ;IAAM,GAAG,oBAACC;GAAK,OAAO;GAAI,QAAQ;IAAM;GACrE;AAGX,QACE,qBAAC;EAAI,WAAW,OAAO;aACpB,SAAS,oBAAC;GAAK,WAAW,OAAO;aAAW;IAAa,EACzD,SACC,oBAACC;GACC,cAAY;GACZ,cAAa;GACb,cAAc;GACd,WAAW,EAAE,sCAAsC;GACnD,UAAU;GACV;GACA,WAAW,EAAE,sCAAsC;GAC5C;IACP,GAEF,qBAAC;GAAI,WAAW,OAAO;cACrB,oBAAC;IAAK,WAAW,OAAO;cAAe;KAAa,EACnD;IACG;GAEJ;;AAIV,2BAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopyableText.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/CopyableText/CopyableText.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAuCpD,CAAC;AAEJ,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"CopyableText.styles.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/CopyableText/CopyableText.styles.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAIzC,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA0CpD,CAAC;AAEJ,eAAe,SAAS,CAAC"}
@@ -10,8 +10,11 @@ const useStyles = (theme) => useMemo(() => ({
10
10
  width: 100%;
11
11
  `,
12
12
  copyButton: css`
13
- flex-shrink: 0;
14
- white-space: nowrap;
13
+ color: ${theme.vars.colors.text.secondary};
14
+
15
+ &:hover:not(:disabled) {
16
+ color: ${theme.vars.colors.text.primary};
17
+ }
15
18
  `,
16
19
  label: css`
17
20
  color: ${theme.vars.colors.text.secondary};
@@ -1 +1 @@
1
- {"version":3,"file":"CopyableText.styles.js","names":[],"sources":["../../../../src/components/primitives/CopyableText/CopyableText.styles.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\nimport {css} from '../../../styles/emotion';\n\nconst useStyles = (theme: Theme): Record<string, string> =>\n useMemo(\n () => ({\n container: css`\n display: flex;\n flex-direction: column;\n gap: calc(${theme.vars.spacing.unit} * 0.5);\n width: 100%;\n `,\n copyButton: css`\n flex-shrink: 0;\n white-space: nowrap;\n `,\n label: css`\n color: ${theme.vars.colors.text.secondary};\n font-size: 0.875rem;\n font-weight: 500;\n `,\n valueBox: css`\n align-items: center;\n background-color: ${theme.vars.colors.background.surface};\n border: 1px solid ${theme.vars.colors.border};\n border-radius: ${theme.vars.borderRadius.small};\n display: flex;\n gap: calc(${theme.vars.spacing.unit} * 1);\n padding: calc(${theme.vars.spacing.unit} * 0.75) calc(${theme.vars.spacing.unit} * 1);\n `,\n valueText: css`\n color: ${theme.vars.colors.text.primary};\n flex: 1;\n font-family: monospace;\n font-size: 0.85rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n word-break: break-all;\n `,\n }),\n [theme],\n );\n\nexport default useStyles;\n"],"mappings":";;;;AAOA,MAAM,aAAa,UACjB,eACS;CACL,WAAW,GAAG;;;oBAGA,MAAM,KAAK,QAAQ,KAAK;;;CAGtC,YAAY,GAAG;;;;CAIf,OAAO,GAAG;iBACC,MAAM,KAAK,OAAO,KAAK,UAAU;;;;CAI5C,UAAU,GAAG;;4BAES,MAAM,KAAK,OAAO,WAAW,QAAQ;4BACrC,MAAM,KAAK,OAAO,OAAO;yBAC5B,MAAM,KAAK,aAAa,MAAM;;oBAEnC,MAAM,KAAK,QAAQ,KAAK;wBACpB,MAAM,KAAK,QAAQ,KAAK,gBAAgB,MAAM,KAAK,QAAQ,KAAK;;CAElF,WAAW,GAAG;iBACH,MAAM,KAAK,OAAO,KAAK,QAAQ;;;;;;;;;CAS3C,GACD,CAAC,MAAM,CACR;AAEH,kCAAe"}
1
+ {"version":3,"file":"CopyableText.styles.js","names":[],"sources":["../../../../src/components/primitives/CopyableText/CopyableText.styles.ts"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\nimport {css} from '../../../styles/emotion';\n\nconst useStyles = (theme: Theme): Record<string, string> =>\n useMemo(\n () => ({\n container: css`\n display: flex;\n flex-direction: column;\n gap: calc(${theme.vars.spacing.unit} * 0.5);\n width: 100%;\n `,\n copyButton: css`\n color: ${theme.vars.colors.text.secondary};\n\n &:hover:not(:disabled) {\n color: ${theme.vars.colors.text.primary};\n }\n `,\n label: css`\n color: ${theme.vars.colors.text.secondary};\n font-size: 0.875rem;\n font-weight: 500;\n `,\n valueBox: css`\n align-items: center;\n background-color: ${theme.vars.colors.background.surface};\n border: 1px solid ${theme.vars.colors.border};\n border-radius: ${theme.vars.borderRadius.small};\n display: flex;\n gap: calc(${theme.vars.spacing.unit} * 1);\n padding: calc(${theme.vars.spacing.unit} * 0.75) calc(${theme.vars.spacing.unit} * 1);\n `,\n valueText: css`\n color: ${theme.vars.colors.text.primary};\n flex: 1;\n font-family: monospace;\n font-size: 0.85rem;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n word-break: break-all;\n `,\n }),\n [theme],\n );\n\nexport default useStyles;\n"],"mappings":";;;;AAOA,MAAM,aAAa,UACjB,eACS;CACL,WAAW,GAAG;;;oBAGA,MAAM,KAAK,QAAQ,KAAK;;;CAGtC,YAAY,GAAG;iBACJ,MAAM,KAAK,OAAO,KAAK,UAAU;;;mBAG/B,MAAM,KAAK,OAAO,KAAK,QAAQ;;;CAG5C,OAAO,GAAG;iBACC,MAAM,KAAK,OAAO,KAAK,UAAU;;;;CAI5C,UAAU,GAAG;;4BAES,MAAM,KAAK,OAAO,WAAW,QAAQ;4BACrC,MAAM,KAAK,OAAO,OAAO;yBAC5B,MAAM,KAAK,aAAa,MAAM;;oBAEnC,MAAM,KAAK,QAAQ,KAAK;wBACpB,MAAM,KAAK,QAAQ,KAAK,gBAAgB,MAAM,KAAK,QAAQ,KAAK;;CAElF,WAAW,GAAG;iBACH,MAAM,KAAK,OAAO,KAAK,QAAQ;;;;;;;;;CAS3C,GACD,CAAC,MAAM,CACR;AAEH,kCAAe"}
@@ -0,0 +1,7 @@
1
+ import { FC, SVGProps } from 'react';
2
+ /**
3
+ * Copy icon component.
4
+ */
5
+ declare const Copy: FC<SVGProps<SVGSVGElement>>;
6
+ export default Copy;
7
+ //# sourceMappingURL=Copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Copy.d.ts","sourceRoot":"","sources":["../../../../src/components/primitives/Icons/Copy.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAC,EAAE,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AAEnC;;GAEG;AACH,QAAA,MAAM,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAgBrC,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+
3
+ //#region src/components/primitives/Icons/Copy.tsx
4
+ /**
5
+ * Copy icon component.
6
+ */
7
+ const Copy = (props) => /* @__PURE__ */ jsxs("svg", {
8
+ xmlns: "http://www.w3.org/2000/svg",
9
+ width: "24",
10
+ height: "24",
11
+ viewBox: "0 0 24 24",
12
+ fill: "none",
13
+ stroke: "currentColor",
14
+ strokeWidth: "2",
15
+ strokeLinecap: "round",
16
+ strokeLinejoin: "round",
17
+ ...props,
18
+ children: [/* @__PURE__ */ jsx("rect", {
19
+ width: "14",
20
+ height: "14",
21
+ x: "8",
22
+ y: "8",
23
+ rx: "2",
24
+ ry: "2"
25
+ }), /* @__PURE__ */ jsx("path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2" })]
26
+ });
27
+ var Copy_default = Copy;
28
+
29
+ //#endregion
30
+ export { Copy_default as default };
31
+ //# sourceMappingURL=Copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Copy.js","names":["Copy: FC<SVGProps<SVGSVGElement>>"],"sources":["../../../../src/components/primitives/Icons/Copy.tsx"],"sourcesContent":["// Copyright 2026 The ThunderID Authors\n// SPDX-License-Identifier: Apache-2.0\n\nimport {FC, SVGProps} from 'react';\n\n/**\n * Copy icon component.\n */\nconst Copy: FC<SVGProps<SVGSVGElement>> = (props: SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\" />\n <path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\" />\n </svg>\n);\n\nexport default Copy;\n"],"mappings":";;;;;;AAQA,MAAMA,QAAqC,UACzC,qBAAC;CACC,OAAM;CACN,OAAM;CACN,QAAO;CACP,SAAQ;CACR,MAAK;CACL,QAAO;CACP,aAAY;CACZ,eAAc;CACd,gBAAe;CACf,GAAI;YAEJ,oBAAC;EAAK,OAAM;EAAK,QAAO;EAAK,GAAE;EAAI,GAAE;EAAI,IAAG;EAAI,IAAG;GAAM,EACzD,oBAAC,UAAK,GAAE,4DAA4D;EAChE;AAGR,mBAAe"}