@thunderid/react 0.10.0 → 0.11.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.
- package/dist/cjs/components/adapters/Consent.cjs +96 -9
- package/dist/cjs/components/adapters/Consent.cjs.map +1 -1
- package/dist/cjs/components/adapters/ConsentCheckboxList.cjs +8 -6
- package/dist/cjs/components/adapters/ConsentCheckboxList.cjs.map +1 -1
- package/dist/cjs/components/adapters/ConsentCheckboxList.styles.cjs +1 -0
- package/dist/cjs/components/adapters/ConsentCheckboxList.styles.cjs.map +1 -1
- package/dist/cjs/components/presentation/UserDropdown/BaseUserDropdown.cjs +2 -2
- package/dist/cjs/components/presentation/UserProfile/BaseUserProfile.cjs +1 -1
- package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs +23 -4
- package/dist/cjs/components/presentation/auth/AuthOptionFactory.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/Recovery/BaseRecovery.cjs +2 -1
- package/dist/cjs/components/presentation/auth/Recovery/BaseRecovery.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs +16 -2
- package/dist/cjs/components/presentation/auth/SignIn/BaseSignIn.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignIn/SignIn.cjs +19 -9
- package/dist/cjs/components/presentation/auth/SignIn/SignIn.cjs.map +1 -1
- package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs +2 -1
- package/dist/cjs/components/presentation/auth/SignUp/BaseSignUp.cjs.map +1 -1
- package/dist/cjs/components/primitives/Dialog/Dialog.cjs +1 -1
- package/dist/cjs/components/primitives/KeyValueInput/KeyValueInput.cjs +1 -1
- package/dist/cjs/components/primitives/PasswordField/PasswordField.cjs +1 -1
- package/dist/cjs/components/primitives/Tooltip/Tooltip.cjs +60 -0
- package/dist/cjs/components/primitives/Tooltip/Tooltip.cjs.map +1 -0
- package/dist/cjs/components/primitives/Tooltip/Tooltip.styles.cjs +110 -0
- package/dist/cjs/components/primitives/Tooltip/Tooltip.styles.cjs.map +1 -0
- package/dist/cjs/hooks/useForm.cjs +30 -19
- package/dist/cjs/hooks/useForm.cjs.map +1 -1
- package/dist/cjs/index.cjs +8 -8
- package/dist/cjs/utils/buildThemeConfigFromFlowMeta.cjs +6 -7
- package/dist/cjs/utils/buildThemeConfigFromFlowMeta.cjs.map +1 -1
- package/dist/components/adapters/Consent.d.ts +23 -1
- package/dist/components/adapters/Consent.d.ts.map +1 -1
- package/dist/components/adapters/Consent.js +96 -10
- package/dist/components/adapters/Consent.js.map +1 -1
- package/dist/components/adapters/ConsentCheckboxList.d.ts.map +1 -1
- package/dist/components/adapters/ConsentCheckboxList.js +8 -6
- package/dist/components/adapters/ConsentCheckboxList.js.map +1 -1
- package/dist/components/adapters/ConsentCheckboxList.styles.d.ts.map +1 -1
- package/dist/components/adapters/ConsentCheckboxList.styles.js +1 -0
- package/dist/components/adapters/ConsentCheckboxList.styles.js.map +1 -1
- package/dist/components/presentation/UserDropdown/BaseUserDropdown.js +2 -2
- package/dist/components/presentation/UserProfile/BaseUserProfile.js +1 -1
- package/dist/components/presentation/auth/AuthOptionFactory.d.ts.map +1 -1
- package/dist/components/presentation/auth/AuthOptionFactory.js +23 -4
- package/dist/components/presentation/auth/AuthOptionFactory.js.map +1 -1
- package/dist/components/presentation/auth/Recovery/BaseRecovery.d.ts +7 -0
- package/dist/components/presentation/auth/Recovery/BaseRecovery.d.ts.map +1 -1
- package/dist/components/presentation/auth/Recovery/BaseRecovery.js +2 -1
- package/dist/components/presentation/auth/Recovery/BaseRecovery.js.map +1 -1
- package/dist/components/presentation/auth/SignIn/BaseSignIn.d.ts +7 -0
- package/dist/components/presentation/auth/SignIn/BaseSignIn.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignIn/BaseSignIn.js +16 -2
- package/dist/components/presentation/auth/SignIn/BaseSignIn.js.map +1 -1
- package/dist/components/presentation/auth/SignIn/SignIn.d.ts +7 -0
- package/dist/components/presentation/auth/SignIn/SignIn.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignIn/SignIn.js +19 -9
- package/dist/components/presentation/auth/SignIn/SignIn.js.map +1 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts +7 -0
- package/dist/components/presentation/auth/SignUp/BaseSignUp.d.ts.map +1 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.js +2 -1
- package/dist/components/presentation/auth/SignUp/BaseSignUp.js.map +1 -1
- package/dist/components/primitives/Dialog/Dialog.js +1 -1
- package/dist/components/primitives/KeyValueInput/KeyValueInput.js +1 -1
- package/dist/components/primitives/PasswordField/PasswordField.js +1 -1
- package/dist/components/primitives/Tooltip/Tooltip.d.ts +40 -0
- package/dist/components/primitives/Tooltip/Tooltip.d.ts.map +1 -0
- package/dist/components/primitives/Tooltip/Tooltip.js +55 -0
- package/dist/components/primitives/Tooltip/Tooltip.js.map +1 -0
- package/dist/components/primitives/Tooltip/Tooltip.styles.d.ts +21 -0
- package/dist/components/primitives/Tooltip/Tooltip.styles.d.ts.map +1 -0
- package/dist/components/primitives/Tooltip/Tooltip.styles.js +107 -0
- package/dist/components/primitives/Tooltip/Tooltip.styles.js.map +1 -0
- package/dist/hooks/useForm.d.ts +13 -1
- package/dist/hooks/useForm.d.ts.map +1 -1
- package/dist/hooks/useForm.js +30 -19
- package/dist/hooks/useForm.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/utils/buildThemeConfigFromFlowMeta.d.ts.map +1 -1
- package/dist/utils/buildThemeConfigFromFlowMeta.js +5 -7
- package/dist/utils/buildThemeConfigFromFlowMeta.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForm.cjs","names":["getFieldConfig: (name: keyof T) => FormField | undefined","validateField: (name: keyof T) => string | null","value: string","fieldConfig: FormField | undefined","fieldError: string | null","validateForm: () => ValidationResult","newErrors: Record<keyof T, string>","error: string | null","globalErrors: Record<string, string>","isValid: boolean","setValue: (name: keyof T, value: string) => void","setValues: (newValues: Partial<T>) => void","setTouched: (name: keyof T, isTouched?: boolean) => void","setTouchedFields: (touchedFields: Partial<Record<keyof T, boolean>>) => void","touchAllFields: () => void","setError: (name: keyof T, error: string) => void","setErrors: (newErrors: Partial<Record<keyof T, string>>) => void","clearErrors: () => void","reset: () => void","handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (e?: FormEvent) => Promise<void>"],"sources":["../../../src/hooks/useForm.ts"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {useState, useCallback, FormEvent} from 'react';\n\n/**\n * Generic form field configuration\n */\nexport interface FormField {\n initialValue?: string;\n name: string;\n required?: boolean;\n validator?: (value: string) => string | null;\n}\n\n/**\n * Form validation result\n */\nexport interface ValidationResult {\n errors: Record<string, string>;\n isValid: boolean;\n}\n\n/**\n * Configuration for the useForm hook\n */\nexport interface UseFormConfig<T extends Record<string, string>> {\n /**\n * Form field definitions\n */\n fields?: FormField[];\n /**\n * Initial form values\n */\n initialValues?: Partial<T>;\n /**\n * Custom required field validation message\n */\n requiredMessage?: string;\n /**\n * Whether to validate on blur (default: true)\n */\n validateOnBlur?: boolean;\n /**\n * Whether to validate on change (default: false)\n */\n validateOnChange?: boolean;\n /**\n * Global form validator function\n */\n validator?: (values: T) => Record<string, string>;\n}\n\n/**\n * Return type for the useForm hook\n */\nexport interface UseFormReturn<T extends Record<string, string>> {\n /**\n * Clear all errors\n */\n clearErrors: () => void;\n /**\n * Current validation errors\n */\n errors: Record<keyof T, string>;\n /**\n * Get field props for easy integration with form components\n */\n getFieldProps: (name: keyof T) => {\n error: string | undefined;\n name: keyof T;\n onBlur: () => void;\n onChange: (value: string) => void;\n required: boolean;\n touched: boolean;\n value: string;\n };\n /**\n * Handle form submission\n */\n handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (e?: FormEvent) => Promise<void>;\n /**\n * Whether the form has been submitted\n */\n isSubmitted: boolean;\n /**\n * Whether the form is currently valid\n */\n isValid: boolean;\n /**\n * Reset the form to initial values\n */\n reset: () => void;\n /**\n * Set a field error\n */\n setError: (name: keyof T, error: string) => void;\n /**\n * Set multiple field errors\n */\n setErrors: (errors: Partial<Record<keyof T, string>>) => void;\n /**\n * Mark a field as touched\n */\n setTouched: (name: keyof T, touched?: boolean) => void;\n /**\n * Mark multiple fields as touched\n */\n setTouchedFields: (touched: Partial<Record<keyof T, boolean>>) => void;\n /**\n * Set a single field value\n */\n setValue: (name: keyof T, value: string) => void;\n /**\n * Set multiple field values\n */\n setValues: (values: Partial<T>) => void;\n /**\n * Mark all fields as touched\n */\n touchAllFields: () => void;\n /**\n * Fields that have been touched by the user\n */\n touched: Record<keyof T, boolean>;\n /**\n * Validate a single field\n */\n validateField: (name: keyof T) => string | null;\n /**\n * Validate all fields\n */\n validateForm: () => ValidationResult;\n /**\n * Current form values\n */\n values: T;\n}\n\n/**\n * Generic form hook that provides comprehensive form state management and validation.\n *\n * @template T - The type of form values (must extend Record<string, string>)\n * @param config - Configuration options for the form\n * @returns Form state and methods\n *\n * @example\n * ```tsx\n * interface LoginForm {\n * username: string;\n * password: string;\n * }\n *\n * const {\n * values,\n * touched,\n * errors,\n * isValid,\n * setValue,\n * handleSubmit,\n * getFieldProps\n * } = useForm<LoginForm>({\n * initialValues: { username: '', password: '' },\n * fields: [\n * { name: 'username', required: true },\n * { name: 'password', required: true }\n * ]\n * });\n *\n * const onSubmit = handleSubmit((values) => {\n * console.log('Form submitted:', values);\n * });\n *\n * return (\n * <form onSubmit={onSubmit}>\n * <input {...getFieldProps('username')} />\n * <input {...getFieldProps('password')} type=\"password\" />\n * <button type=\"submit\" disabled={!isValid}>Submit</button>\n * </form>\n * );\n * ```\n */\nexport const useForm = <T extends Record<string, string>>(config: UseFormConfig<T> = {}): UseFormReturn<T> => {\n const {\n initialValues = {} as T,\n fields = [],\n validator,\n validateOnChange = false,\n validateOnBlur = true,\n requiredMessage = 'This field is required',\n } = config;\n\n // Initialize form state\n const [values, setFormValues] = useState<T>({...initialValues} as T);\n const [touched, setFormTouched] = useState<Record<keyof T, boolean>>({} as Record<keyof T, boolean>);\n const [errors, setFormErrors] = useState<Record<keyof T, string>>({} as Record<keyof T, string>);\n const [isSubmitted, setIsSubmitted] = useState(false);\n\n // Get field configuration by name\n const getFieldConfig: (name: keyof T) => FormField | undefined = useCallback(\n (name: keyof T): FormField | undefined => fields.find((field: FormField) => field.name === name),\n [fields],\n );\n\n // Validate a single field\n const validateField: (name: keyof T) => string | null = useCallback(\n (name: keyof T): string | null => {\n const value: string = values[name] || '';\n const fieldConfig: FormField | undefined = getFieldConfig(name);\n\n // Check required validation\n if (fieldConfig?.required && (!value || value.trim() === '')) {\n return requiredMessage;\n }\n\n // Run custom field validator\n if (fieldConfig?.validator) {\n const fieldError: string | null = fieldConfig.validator(value);\n if (fieldError) return fieldError;\n }\n\n return null;\n },\n [values, getFieldConfig, requiredMessage],\n );\n\n // Validate the entire form\n const validateForm: () => ValidationResult = useCallback((): ValidationResult => {\n const newErrors: Record<keyof T, string> = {} as Record<keyof T, string>;\n\n // Validate individual fields\n fields.forEach((field: FormField) => {\n const error: string | null = validateField(field.name as keyof T);\n if (error) {\n newErrors[field.name as keyof T] = error;\n }\n });\n\n // Run global validator if provided\n if (validator) {\n const globalErrors: Record<string, string> = validator(values);\n Object.keys(globalErrors).forEach((key: string) => {\n if (globalErrors[key]) {\n newErrors[key as keyof T] = globalErrors[key];\n }\n });\n }\n\n return {\n errors: newErrors,\n isValid: Object.keys(newErrors).length === 0,\n };\n }, [fields, validateField, validator, values]);\n\n // Check if form is currently valid\n const isValid: boolean = Object.keys(errors).length === 0;\n\n // Set a single field value\n const setValue: (name: keyof T, value: string) => void = useCallback(\n (name: keyof T, value: string): void => {\n setFormValues((prev: T) => ({\n ...prev,\n [name]: value,\n }));\n\n // Validate on change if enabled\n if (validateOnChange) {\n const error: string | null = validateField(name);\n setFormErrors((prev: Record<keyof T, string>) => {\n const newErrors: Record<keyof T, string> = {...prev};\n if (error) {\n newErrors[name] = error;\n } else {\n delete newErrors[name];\n }\n return newErrors;\n });\n }\n },\n [validateField, validateOnChange],\n );\n\n // Set multiple field values\n const setValues: (newValues: Partial<T>) => void = useCallback((newValues: Partial<T>): void => {\n setFormValues((prev: T) => ({\n ...prev,\n ...newValues,\n }));\n }, []);\n\n // Mark a field as touched\n const setTouched: (name: keyof T, isTouched?: boolean) => void = useCallback(\n (name: keyof T, isTouched = true): void => {\n setFormTouched((prev: Record<keyof T, boolean>) => ({\n ...prev,\n [name]: isTouched,\n }));\n\n // Validate on blur if enabled and field is touched\n if (validateOnBlur && isTouched) {\n const error: string | null = validateField(name);\n setFormErrors((prev: Record<keyof T, string>) => {\n const newErrors: Record<keyof T, string> = {...prev};\n if (error) {\n newErrors[name] = error;\n } else {\n delete newErrors[name];\n }\n return newErrors;\n });\n }\n },\n [validateField, validateOnBlur],\n );\n\n // Set multiple touched fields\n const setTouchedFields: (touchedFields: Partial<Record<keyof T, boolean>>) => void = useCallback(\n (touchedFields: Partial<Record<keyof T, boolean>>): void => {\n setFormTouched((prev: Record<keyof T, boolean>) => ({\n ...prev,\n ...touchedFields,\n }));\n },\n [],\n );\n\n // Mark all fields as touched\n const touchAllFields: () => void = useCallback((): void => {\n const allTouched: Record<keyof T, boolean> = fields.reduce(\n (acc: Record<keyof T, boolean>, field: FormField) => {\n acc[field.name as keyof T] = true;\n return acc;\n },\n {} as Record<keyof T, boolean>,\n );\n\n setFormTouched(allTouched);\n\n // Validate all fields\n const validation: ValidationResult = validateForm();\n setFormErrors(validation.errors as Record<keyof T, string>);\n }, [fields, validateForm]);\n\n // Set a field error\n const setError: (name: keyof T, error: string) => void = useCallback((name: keyof T, error: string): void => {\n setFormErrors((prev: Record<keyof T, string>) => ({\n ...prev,\n [name]: error,\n }));\n }, []);\n\n // Set multiple field errors\n const setErrors: (newErrors: Partial<Record<keyof T, string>>) => void = useCallback(\n (newErrors: Partial<Record<keyof T, string>>): void => {\n setFormErrors((prev: Record<keyof T, string>) => ({\n ...prev,\n ...newErrors,\n }));\n },\n [],\n );\n\n // Clear all errors\n const clearErrors: () => void = useCallback((): void => {\n setFormErrors({} as Record<keyof T, string>);\n }, []);\n\n // Reset form to initial state\n const reset: () => void = useCallback((): void => {\n setFormValues({...initialValues} as T);\n setFormTouched({} as Record<keyof T, boolean>);\n setFormErrors({} as Record<keyof T, string>);\n setIsSubmitted(false);\n }, [initialValues]);\n\n // Handle form submission\n const handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (e?: FormEvent) => Promise<void> = useCallback(\n (onSubmit: (values: T) => void | Promise<void>) =>\n async (e?: FormEvent): Promise<void> => {\n if (e) {\n e.preventDefault();\n }\n\n setIsSubmitted(true);\n touchAllFields();\n\n const validation: ValidationResult = validateForm();\n\n if (validation.isValid) {\n await onSubmit(values);\n }\n },\n [values, touchAllFields, validateForm],\n );\n\n // Get field props for easy integration\n const getFieldProps: (name: keyof T) => any = useCallback(\n (name: keyof T) => {\n const fieldConfig: FormField | undefined = getFieldConfig(name);\n\n return {\n error: touched[name] ? errors[name] : undefined,\n name,\n onBlur: (): void => setTouched(name, true),\n onChange: (value: string): void => setValue(name, value),\n required: fieldConfig?.required || false,\n touched: touched[name] || false,\n value: values[name] || '',\n };\n },\n [values, errors, touched, setValue, setTouched, getFieldConfig],\n );\n\n return {\n clearErrors,\n errors,\n getFieldProps,\n handleSubmit,\n isSubmitted,\n isValid,\n reset,\n setError,\n setErrors,\n setTouched,\n setTouchedFields,\n setValue,\n setValues,\n touchAllFields,\n touched,\n validateField,\n validateForm,\n values,\n };\n};\n\nexport default useForm;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useForm.cjs","names":["fieldError: string | null","getFieldConfig: (name: keyof T) => FormField | undefined","validateField: (name: keyof T) => string | null","validateForm: () => ValidationResult","newErrors: Record<keyof T, string>","error: string | null","globalErrors: Record<string, string>","isValid: boolean","setValue: (name: keyof T, value: string) => void","setValues: (newValues: Partial<T>) => void","setTouched: (name: keyof T, isTouched?: boolean) => void","setTouchedFields: (touchedFields: Partial<Record<keyof T, boolean>>) => void","touchAllFields: () => void","setError: (name: keyof T, error: string) => void","setErrors: (newErrors: Partial<Record<keyof T, string>>) => void","clearErrors: () => void","reset: () => void","handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (e?: FormEvent) => Promise<void>","fieldConfig: FormField | undefined"],"sources":["../../../src/hooks/useForm.ts"],"sourcesContent":["/**\n * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {useState, useCallback, FormEvent} from 'react';\n\n/**\n * Generic form field configuration\n */\nexport interface FormField {\n initialValue?: string;\n name: string;\n required?: boolean;\n validator?: (value: string) => string | null;\n}\n\n/**\n * Form validation result\n */\nexport interface ValidationResult {\n errors: Record<string, string>;\n isValid: boolean;\n}\n\n/**\n * Configuration for the useForm hook\n */\nexport interface UseFormConfig<T extends Record<string, string>> {\n /**\n * Form field definitions\n */\n fields?: FormField[];\n /**\n * Initial form values\n */\n initialValues?: Partial<T>;\n /**\n * Custom required field validation message\n */\n requiredMessage?: string;\n /**\n * When a field has been touched (blurred at least once), re-run validation on every\n * subsequent change so a rendered error clears the moment the value becomes valid.\n *\n * Independent of `validateOnChange`: this only affects fields that have already been\n * blurred, so users don't see errors while initially typing. Default `false` to\n * preserve prior behavior; enable per-form for a \"correct-as-you-type\" UX.\n */\n revalidateOnChangeAfterBlur?: boolean;\n /**\n * Whether to validate on blur (default: true)\n */\n validateOnBlur?: boolean;\n /**\n * Whether to validate on change (default: false). When true, every keystroke\n * triggers validation — including the first, which surfaces errors before the user\n * has had a chance to finish typing. Prefer `revalidateOnChangeAfterBlur` for the\n * common \"clear the error as the user corrects\" UX.\n */\n validateOnChange?: boolean;\n /**\n * Global form validator function\n */\n validator?: (values: T) => Record<string, string>;\n}\n\n/**\n * Pure per-field validator. Kept outside `useForm` so `setValue` can validate against\n * the value it just wrote — inline validation via the closure-based `validateField`\n * inside the hook would read stale `values` (state is committed asynchronously).\n */\nconst computeFieldError = (\n value: string,\n fieldConfig: FormField | undefined,\n requiredMessage: string,\n): string | null => {\n if (fieldConfig?.required && (!value || value.trim() === '')) {\n return requiredMessage;\n }\n if (fieldConfig?.validator) {\n const fieldError: string | null = fieldConfig.validator(value);\n if (fieldError) return fieldError;\n }\n return null;\n};\n\n/**\n * Return type for the useForm hook\n */\nexport interface UseFormReturn<T extends Record<string, string>> {\n /**\n * Clear all errors\n */\n clearErrors: () => void;\n /**\n * Current validation errors\n */\n errors: Record<keyof T, string>;\n /**\n * Get field props for easy integration with form components\n */\n getFieldProps: (name: keyof T) => {\n error: string | undefined;\n name: keyof T;\n onBlur: () => void;\n onChange: (value: string) => void;\n required: boolean;\n touched: boolean;\n value: string;\n };\n /**\n * Handle form submission\n */\n handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (e?: FormEvent) => Promise<void>;\n /**\n * Whether the form has been submitted\n */\n isSubmitted: boolean;\n /**\n * Whether the form is currently valid\n */\n isValid: boolean;\n /**\n * Reset the form to initial values\n */\n reset: () => void;\n /**\n * Set a field error\n */\n setError: (name: keyof T, error: string) => void;\n /**\n * Set multiple field errors\n */\n setErrors: (errors: Partial<Record<keyof T, string>>) => void;\n /**\n * Mark a field as touched\n */\n setTouched: (name: keyof T, touched?: boolean) => void;\n /**\n * Mark multiple fields as touched\n */\n setTouchedFields: (touched: Partial<Record<keyof T, boolean>>) => void;\n /**\n * Set a single field value\n */\n setValue: (name: keyof T, value: string) => void;\n /**\n * Set multiple field values\n */\n setValues: (values: Partial<T>) => void;\n /**\n * Mark all fields as touched\n */\n touchAllFields: () => void;\n /**\n * Fields that have been touched by the user\n */\n touched: Record<keyof T, boolean>;\n /**\n * Validate a single field\n */\n validateField: (name: keyof T) => string | null;\n /**\n * Validate all fields\n */\n validateForm: () => ValidationResult;\n /**\n * Current form values\n */\n values: T;\n}\n\n/**\n * Generic form hook that provides comprehensive form state management and validation.\n *\n * @template T - The type of form values (must extend Record<string, string>)\n * @param config - Configuration options for the form\n * @returns Form state and methods\n *\n * @example\n * ```tsx\n * interface LoginForm {\n * username: string;\n * password: string;\n * }\n *\n * const {\n * values,\n * touched,\n * errors,\n * isValid,\n * setValue,\n * handleSubmit,\n * getFieldProps\n * } = useForm<LoginForm>({\n * initialValues: { username: '', password: '' },\n * fields: [\n * { name: 'username', required: true },\n * { name: 'password', required: true }\n * ]\n * });\n *\n * const onSubmit = handleSubmit((values) => {\n * console.log('Form submitted:', values);\n * });\n *\n * return (\n * <form onSubmit={onSubmit}>\n * <input {...getFieldProps('username')} />\n * <input {...getFieldProps('password')} type=\"password\" />\n * <button type=\"submit\" disabled={!isValid}>Submit</button>\n * </form>\n * );\n * ```\n */\nexport const useForm = <T extends Record<string, string>>(config: UseFormConfig<T> = {}): UseFormReturn<T> => {\n const {\n initialValues = {} as T,\n fields = [],\n validator,\n validateOnChange = false,\n validateOnBlur = true,\n revalidateOnChangeAfterBlur = false,\n requiredMessage = 'This field is required',\n } = config;\n\n // Initialize form state\n const [values, setFormValues] = useState<T>({...initialValues} as T);\n const [touched, setFormTouched] = useState<Record<keyof T, boolean>>({} as Record<keyof T, boolean>);\n const [errors, setFormErrors] = useState<Record<keyof T, string>>({} as Record<keyof T, string>);\n const [isSubmitted, setIsSubmitted] = useState(false);\n\n // Get field configuration by name\n const getFieldConfig: (name: keyof T) => FormField | undefined = useCallback(\n (name: keyof T): FormField | undefined => fields.find((field: FormField) => field.name === name),\n [fields],\n );\n\n // Validate a single field against currently-committed state. Used by the blur path\n // (where `values` is already up-to-date) and by `validateForm`.\n const validateField: (name: keyof T) => string | null = useCallback(\n (name: keyof T): string | null => {\n const value: string = values[name] || '';\n const fieldConfig: FormField | undefined = getFieldConfig(name);\n return computeFieldError(value, fieldConfig, requiredMessage);\n },\n [values, getFieldConfig, requiredMessage],\n );\n\n // Validate the entire form\n const validateForm: () => ValidationResult = useCallback((): ValidationResult => {\n const newErrors: Record<keyof T, string> = {} as Record<keyof T, string>;\n\n // Validate individual fields\n fields.forEach((field: FormField) => {\n const error: string | null = validateField(field.name as keyof T);\n if (error) {\n newErrors[field.name as keyof T] = error;\n }\n });\n\n // Run global validator if provided\n if (validator) {\n const globalErrors: Record<string, string> = validator(values);\n Object.keys(globalErrors).forEach((key: string) => {\n if (globalErrors[key]) {\n newErrors[key as keyof T] = globalErrors[key];\n }\n });\n }\n\n return {\n errors: newErrors,\n isValid: Object.keys(newErrors).length === 0,\n };\n }, [fields, validateField, validator, values]);\n\n // Check if form is currently valid\n const isValid: boolean = Object.keys(errors).length === 0;\n\n // Set a single field value.\n //\n // Validation policy:\n // - `validateOnChange: true` → validate on every keystroke.\n // - `revalidateOnChangeAfterBlur: true` → validate only if the field has\n // already been touched (blurred once),\n // so errors clear as the user corrects\n // without appearing while first typing.\n // - both false → no on-change validation.\n //\n // Validation runs against the NEXT value (the string being written) rather than\n // going through `validateField` which reads the stale closed-over `values`. This\n // prevents the one-keystroke-lag bug where the error clears one character late.\n const setValue: (name: keyof T, value: string) => void = useCallback(\n (name: keyof T, value: string): void => {\n setFormValues((prev: T) => ({\n ...prev,\n [name]: value,\n }));\n\n const shouldValidate: boolean = validateOnChange || (revalidateOnChangeAfterBlur && touched[name] === true);\n if (!shouldValidate) {\n return;\n }\n\n const error: string | null = computeFieldError(value, getFieldConfig(name), requiredMessage);\n setFormErrors((prev: Record<keyof T, string>) => {\n const newErrors: Record<keyof T, string> = {...prev};\n if (error) {\n newErrors[name] = error;\n } else {\n delete newErrors[name];\n }\n return newErrors;\n });\n },\n [validateOnChange, revalidateOnChangeAfterBlur, touched, getFieldConfig, requiredMessage],\n );\n\n // Set multiple field values\n const setValues: (newValues: Partial<T>) => void = useCallback((newValues: Partial<T>): void => {\n setFormValues((prev: T) => ({\n ...prev,\n ...newValues,\n }));\n }, []);\n\n // Mark a field as touched\n const setTouched: (name: keyof T, isTouched?: boolean) => void = useCallback(\n (name: keyof T, isTouched = true): void => {\n setFormTouched((prev: Record<keyof T, boolean>) => ({\n ...prev,\n [name]: isTouched,\n }));\n\n // Validate on blur if enabled and field is touched\n if (validateOnBlur && isTouched) {\n const error: string | null = validateField(name);\n setFormErrors((prev: Record<keyof T, string>) => {\n const newErrors: Record<keyof T, string> = {...prev};\n if (error) {\n newErrors[name] = error;\n } else {\n delete newErrors[name];\n }\n return newErrors;\n });\n }\n },\n [validateField, validateOnBlur],\n );\n\n // Set multiple touched fields\n const setTouchedFields: (touchedFields: Partial<Record<keyof T, boolean>>) => void = useCallback(\n (touchedFields: Partial<Record<keyof T, boolean>>): void => {\n setFormTouched((prev: Record<keyof T, boolean>) => ({\n ...prev,\n ...touchedFields,\n }));\n },\n [],\n );\n\n // Mark all fields as touched\n const touchAllFields: () => void = useCallback((): void => {\n const allTouched: Record<keyof T, boolean> = fields.reduce(\n (acc: Record<keyof T, boolean>, field: FormField) => {\n acc[field.name as keyof T] = true;\n return acc;\n },\n {} as Record<keyof T, boolean>,\n );\n\n setFormTouched(allTouched);\n\n // Validate all fields\n const validation: ValidationResult = validateForm();\n setFormErrors(validation.errors as Record<keyof T, string>);\n }, [fields, validateForm]);\n\n // Set a field error\n const setError: (name: keyof T, error: string) => void = useCallback((name: keyof T, error: string): void => {\n setFormErrors((prev: Record<keyof T, string>) => ({\n ...prev,\n [name]: error,\n }));\n }, []);\n\n // Set multiple field errors\n const setErrors: (newErrors: Partial<Record<keyof T, string>>) => void = useCallback(\n (newErrors: Partial<Record<keyof T, string>>): void => {\n setFormErrors((prev: Record<keyof T, string>) => ({\n ...prev,\n ...newErrors,\n }));\n },\n [],\n );\n\n // Clear all errors\n const clearErrors: () => void = useCallback((): void => {\n setFormErrors({} as Record<keyof T, string>);\n }, []);\n\n // Reset form to initial state\n const reset: () => void = useCallback((): void => {\n setFormValues({...initialValues} as T);\n setFormTouched({} as Record<keyof T, boolean>);\n setFormErrors({} as Record<keyof T, string>);\n setIsSubmitted(false);\n }, [initialValues]);\n\n // Handle form submission\n const handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (e?: FormEvent) => Promise<void> = useCallback(\n (onSubmit: (values: T) => void | Promise<void>) =>\n async (e?: FormEvent): Promise<void> => {\n if (e) {\n e.preventDefault();\n }\n\n setIsSubmitted(true);\n touchAllFields();\n\n const validation: ValidationResult = validateForm();\n\n if (validation.isValid) {\n await onSubmit(values);\n }\n },\n [values, touchAllFields, validateForm],\n );\n\n // Get field props for easy integration\n const getFieldProps: (name: keyof T) => any = useCallback(\n (name: keyof T) => {\n const fieldConfig: FormField | undefined = getFieldConfig(name);\n\n return {\n error: touched[name] ? errors[name] : undefined,\n name,\n onBlur: (): void => setTouched(name, true),\n onChange: (value: string): void => setValue(name, value),\n required: fieldConfig?.required || false,\n touched: touched[name] || false,\n value: values[name] || '',\n };\n },\n [values, errors, touched, setValue, setTouched, getFieldConfig],\n );\n\n return {\n clearErrors,\n errors,\n getFieldProps,\n handleSubmit,\n isSubmitted,\n isValid,\n reset,\n setError,\n setErrors,\n setTouched,\n setTouchedFields,\n setValue,\n setValues,\n touchAllFields,\n touched,\n validateField,\n validateForm,\n values,\n };\n};\n\nexport default useForm;\n"],"mappings":"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"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -38,11 +38,14 @@ const require_TriangleAlert = require('./components/primitives/Icons/TriangleAle
|
|
|
38
38
|
const require_Typography = require('./components/primitives/Typography/Typography.cjs');
|
|
39
39
|
const require_Alert = require('./components/primitives/Alert/Alert.cjs');
|
|
40
40
|
const require_Card = require('./components/primitives/Card/Card.cjs');
|
|
41
|
-
const require_Divider = require('./components/primitives/Divider/Divider.cjs');
|
|
42
41
|
const require_FormControl = require('./components/primitives/FormControl/FormControl.cjs');
|
|
43
42
|
const require_InputLabel = require('./components/primitives/InputLabel/InputLabel.cjs');
|
|
44
43
|
const require_Toggle = require('./components/primitives/Toggle/Toggle.cjs');
|
|
45
44
|
const require_ConsentCheckboxList = require('./components/adapters/ConsentCheckboxList.cjs');
|
|
45
|
+
const require_Eye = require('./components/primitives/Icons/Eye.cjs');
|
|
46
|
+
const require_EyeOff = require('./components/primitives/Icons/EyeOff.cjs');
|
|
47
|
+
const require_LogOut = require('./components/primitives/Icons/LogOut.cjs');
|
|
48
|
+
const require_User = require('./components/primitives/Icons/User.cjs');
|
|
46
49
|
const require_Consent = require('./components/adapters/Consent.cjs');
|
|
47
50
|
const require_FacebookButton = require('./components/adapters/FacebookButton.cjs');
|
|
48
51
|
const require_FlowTimer = require('./components/adapters/FlowTimer.cjs');
|
|
@@ -54,12 +57,11 @@ const require_SignInWithEthereumButton = require('./components/adapters/SignInWi
|
|
|
54
57
|
const require_Checkbox = require('./components/primitives/Checkbox/Checkbox.cjs');
|
|
55
58
|
const require_DatePicker = require('./components/primitives/DatePicker/DatePicker.cjs');
|
|
56
59
|
const require_OtpField = require('./components/primitives/OtpField/OtpField.cjs');
|
|
57
|
-
const require_Eye = require('./components/primitives/Icons/Eye.cjs');
|
|
58
|
-
const require_EyeOff = require('./components/primitives/Icons/EyeOff.cjs');
|
|
59
60
|
const require_TextField = require('./components/primitives/TextField/TextField.cjs');
|
|
60
61
|
const require_PasswordField = require('./components/primitives/PasswordField/PasswordField.cjs');
|
|
61
62
|
const require_Select = require('./components/primitives/Select/Select.cjs');
|
|
62
63
|
const require_FieldFactory = require('./components/factories/FieldFactory.cjs');
|
|
64
|
+
const require_Divider = require('./components/primitives/Divider/Divider.cjs');
|
|
63
65
|
const require_BaseSignIn = require('./components/presentation/auth/SignIn/BaseSignIn.cjs');
|
|
64
66
|
const require_useOAuthCallback = require('./hooks/useOAuthCallback.cjs');
|
|
65
67
|
const require_SignIn = require('./components/presentation/auth/SignIn/SignIn.cjs');
|
|
@@ -76,9 +78,7 @@ const require_OAuthCallback = require('./components/auth/Callback/OAuthCallback.
|
|
|
76
78
|
const require_TokenCallback = require('./components/auth/Callback/TokenCallback.cjs');
|
|
77
79
|
const require_Callback = require('./components/auth/Callback/Callback.cjs');
|
|
78
80
|
const require_BaseUser = require('./components/presentation/User/BaseUser.cjs');
|
|
79
|
-
const require_User = require('./components/presentation/User/User.cjs');
|
|
80
|
-
const require_LogOut = require('./components/primitives/Icons/LogOut.cjs');
|
|
81
|
-
const require_User$1 = require('./components/primitives/Icons/User.cjs');
|
|
81
|
+
const require_User$1 = require('./components/presentation/User/User.cjs');
|
|
82
82
|
const require_MultiInput = require('./components/primitives/MultiInput/MultiInput.cjs');
|
|
83
83
|
const require_BaseUserProfile = require('./components/presentation/UserProfile/BaseUserProfile.cjs');
|
|
84
84
|
const require_updateMeProfile = require('./api/updateMeProfile.cjs');
|
|
@@ -263,11 +263,11 @@ exports.Toggle = require_Toggle.default;
|
|
|
263
263
|
exports.TokenCallback = require_TokenCallback.TokenCallback;
|
|
264
264
|
exports.TriangleAlert = require_TriangleAlert.default;
|
|
265
265
|
exports.Typography = require_Typography.default;
|
|
266
|
-
exports.User = require_User.default;
|
|
266
|
+
exports.User = require_User$1.default;
|
|
267
267
|
exports.UserAvatar = require_UserAvatar.default;
|
|
268
268
|
exports.UserContext = require_UserContext.default;
|
|
269
269
|
exports.UserDropdown = require_UserDropdown.default;
|
|
270
|
-
exports.UserIcon = require_User
|
|
270
|
+
exports.UserIcon = require_User.default;
|
|
271
271
|
exports.UserProfile = require_UserProfile.default;
|
|
272
272
|
exports.UserProvider = require_UserProvider.default;
|
|
273
273
|
Object.defineProperty(exports, 'buildAvatarSpec', {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
let __thunderid_browser = require("@thunderid/browser");
|
|
3
|
+
__thunderid_browser = require_rolldown_runtime.__toESM(__thunderid_browser);
|
|
1
4
|
|
|
2
5
|
//#region src/utils/buildThemeConfigFromFlowMeta.ts
|
|
3
6
|
/**
|
|
@@ -15,8 +18,7 @@
|
|
|
15
18
|
*/
|
|
16
19
|
const buildThemeConfigFromFlowMeta = (flowMetaTheme, colorScheme) => {
|
|
17
20
|
const scheme = flowMetaTheme.colorSchemes?.[colorScheme];
|
|
18
|
-
const
|
|
19
|
-
const borderRadiusStr = borderRadius !== void 0 ? `${borderRadius}px` : void 0;
|
|
21
|
+
const borderRadiusConfig = (0, __thunderid_browser.normalizeBorderRadius)(flowMetaTheme.shape?.borderRadius);
|
|
20
22
|
let colors;
|
|
21
23
|
if (scheme?.palette) {
|
|
22
24
|
colors = {};
|
|
@@ -31,12 +33,9 @@ const buildThemeConfigFromFlowMeta = (flowMetaTheme, colorScheme) => {
|
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
return {
|
|
36
|
+
...flowMetaTheme,
|
|
34
37
|
...flowMetaTheme.direction ? { direction: flowMetaTheme.direction } : {},
|
|
35
|
-
...
|
|
36
|
-
large: borderRadiusStr,
|
|
37
|
-
medium: borderRadiusStr,
|
|
38
|
-
small: borderRadiusStr
|
|
39
|
-
} } : {},
|
|
38
|
+
...borderRadiusConfig ? { borderRadius: borderRadiusConfig } : {},
|
|
40
39
|
...colors && Object.keys(colors).length > 0 ? { colors } : {},
|
|
41
40
|
...flowMetaTheme.typography?.fontFamily ? { typography: { fontFamily: flowMetaTheme.typography.fontFamily } } : {}
|
|
42
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildThemeConfigFromFlowMeta.cjs","names":["scheme: FlowMetaThemeColorScheme | undefined","
|
|
1
|
+
{"version":3,"file":"buildThemeConfigFromFlowMeta.cjs","names":["scheme: FlowMetaThemeColorScheme | undefined","colors: RecursivePartial<ThemeConfig['colors']> | undefined","bg: RecursivePartial<ThemeConfig['colors']['background']>"],"sources":["../../../src/utils/buildThemeConfigFromFlowMeta.ts"],"sourcesContent":["/**\n * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {\n FlowMetaTheme,\n FlowMetaThemeColorScheme,\n RecursivePartial,\n ThemeConfig,\n normalizeBorderRadius,\n} from '@thunderid/browser';\n\n/**\n * Converts a v2 `FlowMetaTheme` into a `RecursivePartial<ThemeConfig>` that\n * `createTheme` can consume.\n *\n * Only fields explicitly present in the FlowMeta response are included so that\n * `createTheme` can deep-merge them onto its base (light/dark) defaults without\n * accidentally dropping sibling keys that were not returned by the server.\n *\n * For example, when FlowMeta returns only `background.default` and\n * `background.paper`, only `body.main` and `surface` are set — the base\n * theme's `background.disabled` and `background.dark` are **not** overridden\n * and therefore keep their default CSS variable values.\n */\nconst buildThemeConfigFromFlowMeta = (\n flowMetaTheme: FlowMetaTheme,\n colorScheme: 'light' | 'dark',\n): RecursivePartial<ThemeConfig> => {\n const scheme: FlowMetaThemeColorScheme | undefined = flowMetaTheme.colorSchemes?.[colorScheme];\n const borderRadiusConfig = normalizeBorderRadius(flowMetaTheme.shape?.borderRadius);\n\n // Build only the colors that the server actually provided.\n // Each nested object is constructed incrementally so that absent fields are\n // simply omitted rather than set to `undefined`, which would shadow the\n // base-theme defaults inside `createTheme`.\n let colors: RecursivePartial<ThemeConfig['colors']> | undefined;\n\n if (scheme?.palette) {\n colors = {};\n\n if (scheme.palette.primary) {\n colors.primary = scheme.palette.primary;\n }\n if (scheme.palette.secondary) {\n colors.secondary = scheme.palette.secondary;\n }\n if (scheme.palette.text) {\n colors.text = scheme.palette.text;\n }\n\n // Build background incrementally to avoid replacing the full base object.\n if (scheme.palette.background) {\n const bg: RecursivePartial<ThemeConfig['colors']['background']> = {};\n\n if (scheme.palette.background.default) {\n bg.body = {main: scheme.palette.background.default};\n }\n if (scheme.palette.background.paper) {\n bg.surface = scheme.palette.background.paper;\n }\n\n if (Object.keys(bg).length > 0) {\n colors.background = bg;\n }\n }\n }\n\n return {\n ...flowMetaTheme,\n ...(flowMetaTheme.direction ? {direction: flowMetaTheme.direction} : {}),\n ...(borderRadiusConfig ? {borderRadius: borderRadiusConfig} : {}),\n ...(colors && Object.keys(colors).length > 0 ? {colors} : {}),\n ...(flowMetaTheme.typography?.fontFamily ? {typography: {fontFamily: flowMetaTheme.typography.fontFamily}} : {}),\n };\n};\n\nexport default buildThemeConfigFromFlowMeta;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,MAAM,gCACJ,eACA,gBACkC;CAClC,MAAMA,SAA+C,cAAc,eAAe;CAClF,MAAM,oEAA2C,cAAc,OAAO,aAAa;CAMnF,IAAIC;AAEJ,KAAI,QAAQ,SAAS;AACnB,WAAS,EAAE;AAEX,MAAI,OAAO,QAAQ,QACjB,QAAO,UAAU,OAAO,QAAQ;AAElC,MAAI,OAAO,QAAQ,UACjB,QAAO,YAAY,OAAO,QAAQ;AAEpC,MAAI,OAAO,QAAQ,KACjB,QAAO,OAAO,OAAO,QAAQ;AAI/B,MAAI,OAAO,QAAQ,YAAY;GAC7B,MAAMC,KAA4D,EAAE;AAEpE,OAAI,OAAO,QAAQ,WAAW,QAC5B,IAAG,OAAO,EAAC,MAAM,OAAO,QAAQ,WAAW,SAAQ;AAErD,OAAI,OAAO,QAAQ,WAAW,MAC5B,IAAG,UAAU,OAAO,QAAQ,WAAW;AAGzC,OAAI,OAAO,KAAK,GAAG,CAAC,SAAS,EAC3B,QAAO,aAAa;;;AAK1B,QAAO;EACL,GAAG;EACH,GAAI,cAAc,YAAY,EAAC,WAAW,cAAc,WAAU,GAAG,EAAE;EACvE,GAAI,qBAAqB,EAAC,cAAc,oBAAmB,GAAG,EAAE;EAChE,GAAI,UAAU,OAAO,KAAK,OAAO,CAAC,SAAS,IAAI,EAAC,QAAO,GAAG,EAAE;EAC5D,GAAI,cAAc,YAAY,aAAa,EAAC,YAAY,EAAC,YAAY,cAAc,WAAW,YAAW,EAAC,GAAG,EAAE;EAChH;;AAGH,2CAAe"}
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
* specific language governing permissions and limitations
|
|
16
16
|
* under the License.
|
|
17
17
|
*/
|
|
18
|
-
import { type ConsentPurposeData } from '@thunderid/browser';
|
|
18
|
+
import { type ConsentPurposeData, FlowMetadataResponse } from '@thunderid/browser';
|
|
19
19
|
import { FC, ReactNode } from 'react';
|
|
20
|
+
import { UseTranslation } from '../../hooks/useTranslation';
|
|
20
21
|
/**
|
|
21
22
|
* Backward-compatible consent purpose type exported by @thunderid/react.
|
|
22
23
|
*
|
|
@@ -34,6 +35,15 @@ export interface ConsentRenderProps {
|
|
|
34
35
|
/** The resolved list of consent purposes parsed from `consentData`. */
|
|
35
36
|
purposes: ConsentPurposeData[];
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Interface for consent configuration
|
|
40
|
+
*/
|
|
41
|
+
export interface ConsentConfig {
|
|
42
|
+
essential?: string;
|
|
43
|
+
optional?: string;
|
|
44
|
+
essentialInfo?: string;
|
|
45
|
+
optionalInfo?: string;
|
|
46
|
+
}
|
|
37
47
|
/**
|
|
38
48
|
* Props for the Consent component.
|
|
39
49
|
*/
|
|
@@ -69,6 +79,18 @@ export interface ConsentProps {
|
|
|
69
79
|
* Callback invoked when a user toggles an optional attribute.
|
|
70
80
|
*/
|
|
71
81
|
onInputChange: (name: string, value: string) => void;
|
|
82
|
+
/**
|
|
83
|
+
* Config to modified detail in consent page
|
|
84
|
+
*/
|
|
85
|
+
config?: Record<string, unknown>;
|
|
86
|
+
/**
|
|
87
|
+
* Config of meta response
|
|
88
|
+
*/
|
|
89
|
+
meta?: FlowMetadataResponse | null;
|
|
90
|
+
/**
|
|
91
|
+
* translation data
|
|
92
|
+
*/
|
|
93
|
+
t?: UseTranslation['t'];
|
|
72
94
|
}
|
|
73
95
|
/**
|
|
74
96
|
* Consent component renders the list of purposes and their associated attributes (essential and optional)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Consent.d.ts","sourceRoot":"","sources":["../../../src/components/adapters/Consent.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"Consent.d.ts","sourceRoot":"","sources":["../../../src/components/adapters/Consent.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,KAAK,kBAAkB,EACvB,oBAAoB,EAGrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAmB,EAAE,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AAMtD,OAAO,EAAC,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE1D;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,kEAAkE;IAClE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,uEAAuE;IACvE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,SAAS,CAAC;IACpD;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,kBAAkB,EAAE,GAAG;QAAC,QAAQ,EAAE,kBAAkB,EAAE,CAAA;KAAC,CAAC;IAC/E;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC;;OAEG;IACH,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjC;;OAEG;IACH,IAAI,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAEnC;;OAEG;IACH,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;CACzB;AAOD;;;;GAIG;AACH,QAAA,MAAM,OAAO,EAAE,EAAE,CAAC,YAAY,CA6I7B,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -1,14 +1,59 @@
|
|
|
1
|
+
import Info_default from "../primitives/Icons/Info.js";
|
|
1
2
|
import Typography_default from "../primitives/Typography/Typography.js";
|
|
2
|
-
import
|
|
3
|
+
import Toggle_default from "../primitives/Toggle/Toggle.js";
|
|
4
|
+
import ConsentCheckboxList_default, { getConsentOptionalKey } from "./ConsentCheckboxList.js";
|
|
5
|
+
import Tooltip_default from "../primitives/Tooltip/Tooltip.js";
|
|
6
|
+
import { resolveFlowTemplateLiterals } from "@thunderid/browser";
|
|
3
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
8
|
|
|
5
9
|
//#region src/components/adapters/Consent.tsx
|
|
10
|
+
const defaultConfig = {
|
|
11
|
+
essential: "Essential Attributtes",
|
|
12
|
+
optional: "Optional Attributes"
|
|
13
|
+
};
|
|
6
14
|
/**
|
|
7
15
|
* Consent component renders the list of purposes and their associated attributes (essential and optional)
|
|
8
16
|
* based on the data provided by the backend. It allows users to toggle optional attributes while essential
|
|
9
17
|
* attributes are displayed as read-only.
|
|
10
18
|
*/
|
|
11
|
-
const Consent = ({ consentData, formValues, onInputChange, children }) => {
|
|
19
|
+
const Consent = ({ consentData, formValues, config: suppliedConfig = {}, onInputChange, children, meta, t }) => {
|
|
20
|
+
/** Resolve any remaining {{t()}} or {{meta()}} template expressions in a string at render time. */
|
|
21
|
+
const resolve = (text) => {
|
|
22
|
+
if (!text || !t && !meta) return text || "";
|
|
23
|
+
return resolveFlowTemplateLiterals(text, {
|
|
24
|
+
meta,
|
|
25
|
+
t: t || ((k) => k)
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const config = {
|
|
29
|
+
...defaultConfig,
|
|
30
|
+
...suppliedConfig
|
|
31
|
+
};
|
|
32
|
+
const essentialInfo = typeof config.essentialInfo === "string" ? resolve(config.essentialInfo.trim()) : "";
|
|
33
|
+
const optionalInfo = typeof config.optionalInfo === "string" ? resolve(config.optionalInfo.trim()) : "";
|
|
34
|
+
const essentialLabel = resolve(config["essential"]);
|
|
35
|
+
const optionalLabel = resolve(config["optional"]);
|
|
36
|
+
/**
|
|
37
|
+
* Method to check whether master toggle button is checked or not
|
|
38
|
+
* @param purpose Purpose object
|
|
39
|
+
* @param checked boolean variable to check, whether toggle is checked or unchecked
|
|
40
|
+
*/
|
|
41
|
+
const handleChange = (purpose, checked) => {
|
|
42
|
+
const checkValue = checked ? "true" : "false";
|
|
43
|
+
purpose.optional.map((opt) => {
|
|
44
|
+
onInputChange(getConsentOptionalKey(purpose.purposeId, opt.name), checkValue);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Check all optional claims are selected or not
|
|
49
|
+
* @param purpose Purpose object
|
|
50
|
+
* @returns boolean value to denote all optional claims are selected
|
|
51
|
+
*/
|
|
52
|
+
const checkOptValue = (purpose) => {
|
|
53
|
+
return purpose.optional.every((opt) => {
|
|
54
|
+
return formValues[getConsentOptionalKey(purpose.purposeId, opt.name)] === "true";
|
|
55
|
+
});
|
|
56
|
+
};
|
|
12
57
|
if (!consentData) return null;
|
|
13
58
|
let purposes = [];
|
|
14
59
|
try {
|
|
@@ -34,10 +79,24 @@ const Consent = ({ consentData, formValues, onInputChange, children }) => {
|
|
|
34
79
|
style: { paddingBottom: "1rem" },
|
|
35
80
|
children: [purpose.essential && purpose.essential.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
36
81
|
style: { marginTop: "0.5rem" },
|
|
37
|
-
children: [/* @__PURE__ */
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
82
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
83
|
+
style: {
|
|
84
|
+
display: "flex",
|
|
85
|
+
alignItems: "center",
|
|
86
|
+
gap: "4px",
|
|
87
|
+
marginBottom: "10px"
|
|
88
|
+
},
|
|
89
|
+
children: [/* @__PURE__ */ jsx(Typography_default, {
|
|
90
|
+
variant: "subtitle2",
|
|
91
|
+
fontWeight: "bold",
|
|
92
|
+
children: essentialLabel
|
|
93
|
+
}), essentialInfo !== "" && /* @__PURE__ */ jsx(Tooltip_default, {
|
|
94
|
+
helperText: essentialInfo,
|
|
95
|
+
children: /* @__PURE__ */ jsx(Info_default, {
|
|
96
|
+
width: "1rem",
|
|
97
|
+
height: "1rem"
|
|
98
|
+
})
|
|
99
|
+
})]
|
|
41
100
|
}), /* @__PURE__ */ jsx(ConsentCheckboxList_default, {
|
|
42
101
|
variant: "ESSENTIAL",
|
|
43
102
|
purpose,
|
|
@@ -46,10 +105,37 @@ const Consent = ({ consentData, formValues, onInputChange, children }) => {
|
|
|
46
105
|
})]
|
|
47
106
|
}), purpose.optional && purpose.optional.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
48
107
|
style: { marginTop: "0.5rem" },
|
|
49
|
-
children: [/* @__PURE__ */
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
108
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
109
|
+
style: {
|
|
110
|
+
display: "flex",
|
|
111
|
+
alignItems: "center",
|
|
112
|
+
justifyContent: "space-between",
|
|
113
|
+
paddingRight: "4px",
|
|
114
|
+
marginBottom: "10px"
|
|
115
|
+
},
|
|
116
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
117
|
+
style: {
|
|
118
|
+
display: "flex",
|
|
119
|
+
alignItems: "center",
|
|
120
|
+
gap: "4px"
|
|
121
|
+
},
|
|
122
|
+
children: [/* @__PURE__ */ jsx(Typography_default, {
|
|
123
|
+
variant: "subtitle2",
|
|
124
|
+
fontWeight: "bold",
|
|
125
|
+
children: purpose.type === "permissions" ? "Permissions" : optionalLabel
|
|
126
|
+
}), optionalInfo !== "" && /* @__PURE__ */ jsx(Tooltip_default, {
|
|
127
|
+
helperText: optionalInfo,
|
|
128
|
+
children: /* @__PURE__ */ jsx(Info_default, {
|
|
129
|
+
width: "1rem",
|
|
130
|
+
height: "1rem"
|
|
131
|
+
})
|
|
132
|
+
})]
|
|
133
|
+
}), /* @__PURE__ */ jsx(Toggle_default, {
|
|
134
|
+
id: `consent_opt_${purpose.purposeId}_all`,
|
|
135
|
+
checked: checkOptValue(purpose),
|
|
136
|
+
"aria-label": "Toggle all optional attributes",
|
|
137
|
+
onChange: (e) => handleChange(purpose, e.target.checked)
|
|
138
|
+
})]
|
|
53
139
|
}), /* @__PURE__ */ jsx(ConsentCheckboxList_default, {
|
|
54
140
|
variant: "OPTIONAL",
|
|
55
141
|
purpose,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Consent.js","names":["Consent: FC<ConsentProps>","purposes: ConsentPurposeData[]","parsed: ConsentPurposeData[] | {purposes: ConsentPurposeData[]}","Typography","ConsentCheckboxList"],"sources":["../../../src/components/adapters/Consent.tsx"],"sourcesContent":["/**\n * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {type ConsentPurposeData} from '@thunderid/browser';\nimport {FC, ReactNode} from 'react';\nimport ConsentCheckboxList from './ConsentCheckboxList';\nimport Typography from '../primitives/Typography/Typography';\n\n/**\n * Backward-compatible consent purpose type exported by @thunderid/react.\n *\n * Some consumers import this name directly; keep it as an alias to the v2 model.\n */\nexport type ConsentPurpose = ConsentPurposeData;\n\n/**\n * Render props exposed by Consent when using the render-prop pattern.\n */\nexport interface ConsentRenderProps {\n /** Current form values - used to read optional checkbox state. */\n formValues: Record<string, string>;\n /** Callback invoked when a user toggles an optional attribute. */\n onInputChange: (name: string, value: string) => void;\n /** The resolved list of consent purposes parsed from `consentData`. */\n purposes: ConsentPurposeData[];\n}\n\n/**\n * Props for the Consent component.\n */\nexport interface ConsentProps {\n /**\n * Render-props callback. When provided, the default consent UI is replaced with\n * whatever JSX the callback returns. The parsed `purposes` list is injected so\n * consumers do not need to re-parse `consentData` themselves.\n *\n * @example\n * ```tsx\n * <Consent consentData={raw} formValues={formInputs} onInputChange={onChange} t={t}>\n * {({ purposes, formValues, onInputChange, t }) => (\n * <div>\n * {purposes.map(p => <MyConsentSection key={p.purposeId} purpose={p} />)}\n * </div>\n * )}\n * </Consent>\n * ```\n */\n children?: (props: ConsentRenderProps) => ReactNode;\n /**\n * The raw JSON string returned by the backend in `additionalData.consentPrompt`.\n */\n consentData?: string | ConsentPurposeData[] | {purposes: ConsentPurposeData[]};\n /**\n * Current form values - used to read optional checkbox state.\n */\n formValues: Record<string, string>;\n /**\n * Callback invoked when a user toggles an optional attribute.\n */\n onInputChange: (name: string, value: string) => void;\n}\n\n/**\n * Consent component renders the list of purposes and their associated attributes (essential and optional)\n * based on the data provided by the backend. It allows users to toggle optional attributes while essential\n * attributes are displayed as read-only.\n */\nconst Consent: FC<ConsentProps> = ({consentData, formValues, onInputChange, children}: ConsentProps) => {\n if (!consentData) return null;\n\n let purposes: ConsentPurposeData[] = [];\n\n try {\n const parsed: ConsentPurposeData[] | {purposes: ConsentPurposeData[]} =\n typeof consentData === 'string' ? JSON.parse(consentData) : consentData;\n\n purposes = Array.isArray(parsed) ? parsed : parsed.purposes || [];\n } catch (e) {\n // Failed to parse consent prompt data\n return null;\n }\n\n if (purposes.length === 0) return null;\n\n if (children) {\n return <>{children({formValues, onInputChange, purposes: purposes})}</>;\n }\n\n return (\n <div style={{display: 'flex', flexDirection: 'column', gap: '1rem', marginTop: '0.25rem'}}>\n {purposes.map((purpose: ConsentPurposeData, purposeIndex: number) => (\n <div key={purpose.purposeId || purposeIndex} style={{paddingBottom: '1rem'}}>\n {/* TODO: Uncomment when the backend supports multiple purposes for a application */}\n {/* <Typography variant=\"h6\" fontWeight={600} gutterBottom color=\"inherit\">\n {purpose.purposeName}\n </Typography>\n <Typography variant=\"body2\" color=\"inherit\" style={{marginBottom: '1rem', opacity: 0.85}}>\n {purpose.description}\n </Typography> */}\n\n {purpose.essential && purpose.essential.length > 0 && (\n <div style={{marginTop: '0.5rem'}}>\n <Typography variant=\"subtitle2\" fontWeight=\"bold\">\n Essential Attributes\n </Typography>\n <ConsentCheckboxList\n variant=\"ESSENTIAL\"\n purpose={purpose}\n formValues={formValues}\n onInputChange={onInputChange}\n />\n </div>\n )}\n\n {purpose.optional && purpose.optional.length > 0 && (\n <div style={{marginTop: '0.5rem'}}>\n <Typography variant=\"subtitle2\" fontWeight=\"bold\">\n {purpose.type === 'permissions' ? 'Permissions' : 'Optional Attributes'}\n </Typography>\n <ConsentCheckboxList\n variant=\"OPTIONAL\"\n purpose={purpose}\n formValues={formValues}\n onInputChange={onInputChange}\n />\n </div>\n )}\n </div>\n ))}\n </div>\n );\n};\n\nexport default Consent;\n"],"mappings":";;;;;;;;;;AAkFA,MAAMA,WAA6B,EAAC,aAAa,YAAY,eAAe,eAA4B;AACtG,KAAI,CAAC,YAAa,QAAO;CAEzB,IAAIC,WAAiC,EAAE;AAEvC,KAAI;EACF,MAAMC,SACJ,OAAO,gBAAgB,WAAW,KAAK,MAAM,YAAY,GAAG;AAE9D,aAAW,MAAM,QAAQ,OAAO,GAAG,SAAS,OAAO,YAAY,EAAE;UAC1D,GAAG;AAEV,SAAO;;AAGT,KAAI,SAAS,WAAW,EAAG,QAAO;AAElC,KAAI,SACF,QAAO,0CAAG,SAAS;EAAC;EAAY;EAAyB;EAAS,CAAC,GAAI;AAGzE,QACE,oBAAC;EAAI,OAAO;GAAC,SAAS;GAAQ,eAAe;GAAU,KAAK;GAAQ,WAAW;GAAU;YACtF,SAAS,KAAK,SAA6B,iBAC1C,qBAAC;GAA4C,OAAO,EAAC,eAAe,QAAO;cASxE,QAAQ,aAAa,QAAQ,UAAU,SAAS,KAC/C,qBAAC;IAAI,OAAO,EAAC,WAAW,UAAS;eAC/B,oBAACC;KAAW,SAAQ;KAAY,YAAW;eAAO;MAErC,EACb,oBAACC;KACC,SAAQ;KACC;KACG;KACG;MACf;KACE,EAGP,QAAQ,YAAY,QAAQ,SAAS,SAAS,KAC7C,qBAAC;IAAI,OAAO,EAAC,WAAW,UAAS;eAC/B,oBAACD;KAAW,SAAQ;KAAY,YAAW;eACxC,QAAQ,SAAS,gBAAgB,gBAAgB;MACvC,EACb,oBAACC;KACC,SAAQ;KACC;KACG;KACG;MACf;KACE;KAlCA,QAAQ,aAAa,aAoCzB,CACN;GACE;;AAIV,sBAAe"}
|
|
1
|
+
{"version":3,"file":"Consent.js","names":["defaultConfig: Required<Pick<ConsentConfig, 'essential' | 'optional'>>","Consent: FC<ConsentProps>","config: ConsentConfig","purposes: ConsentPurposeData[]","parsed: ConsentPurposeData[] | {purposes: ConsentPurposeData[]}","Typography","Tooltip","Info","ConsentCheckboxList","Toggle"],"sources":["../../../src/components/adapters/Consent.tsx"],"sourcesContent":["/**\n * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {\n type ConsentPurposeData,\n FlowMetadataResponse,\n PromptElement,\n resolveFlowTemplateLiterals,\n} from '@thunderid/browser';\nimport {type ChangeEvent, FC, ReactNode} from 'react';\nimport ConsentCheckboxList, {getConsentOptionalKey} from './ConsentCheckboxList';\nimport Typography from '../primitives/Typography/Typography';\nimport Toggle from '../primitives/Toggle/Toggle';\nimport {Info} from '../primitives/Icons';\nimport Tooltip from '../primitives/Tooltip/Tooltip';\nimport {UseTranslation} from '../../hooks/useTranslation';\n\n/**\n * Backward-compatible consent purpose type exported by @thunderid/react.\n *\n * Some consumers import this name directly; keep it as an alias to the v2 model.\n */\nexport type ConsentPurpose = ConsentPurposeData;\n\n/**\n * Render props exposed by Consent when using the render-prop pattern.\n */\nexport interface ConsentRenderProps {\n /** Current form values - used to read optional checkbox state. */\n formValues: Record<string, string>;\n /** Callback invoked when a user toggles an optional attribute. */\n onInputChange: (name: string, value: string) => void;\n /** The resolved list of consent purposes parsed from `consentData`. */\n purposes: ConsentPurposeData[];\n}\n\n/**\n * Interface for consent configuration\n */\nexport interface ConsentConfig {\n essential?: string;\n optional?: string;\n essentialInfo?: string;\n optionalInfo?: string;\n}\n\n/**\n * Props for the Consent component.\n */\nexport interface ConsentProps {\n /**\n * Render-props callback. When provided, the default consent UI is replaced with\n * whatever JSX the callback returns. The parsed `purposes` list is injected so\n * consumers do not need to re-parse `consentData` themselves.\n *\n * @example\n * ```tsx\n * <Consent consentData={raw} formValues={formInputs} onInputChange={onChange} t={t}>\n * {({ purposes, formValues, onInputChange, t }) => (\n * <div>\n * {purposes.map(p => <MyConsentSection key={p.purposeId} purpose={p} />)}\n * </div>\n * )}\n * </Consent>\n * ```\n */\n children?: (props: ConsentRenderProps) => ReactNode;\n /**\n * The raw JSON string returned by the backend in `additionalData.consentPrompt`.\n */\n consentData?: string | ConsentPurposeData[] | {purposes: ConsentPurposeData[]};\n /**\n * Current form values - used to read optional checkbox state.\n */\n formValues: Record<string, string>;\n /**\n * Callback invoked when a user toggles an optional attribute.\n */\n onInputChange: (name: string, value: string) => void;\n /**\n * Config to modified detail in consent page\n */\n config?: Record<string, unknown>;\n\n /**\n * Config of meta response\n */\n meta?: FlowMetadataResponse | null;\n\n /**\n * translation data\n */\n t?: UseTranslation['t'];\n}\n\nconst defaultConfig: Required<Pick<ConsentConfig, 'essential' | 'optional'>> = {\n essential: 'Essential Attributtes',\n optional: 'Optional Attributes',\n};\n\n/**\n * Consent component renders the list of purposes and their associated attributes (essential and optional)\n * based on the data provided by the backend. It allows users to toggle optional attributes while essential\n * attributes are displayed as read-only.\n */\nconst Consent: FC<ConsentProps> = ({\n consentData,\n formValues,\n config: suppliedConfig = {},\n onInputChange,\n children,\n meta,\n t,\n}: ConsentProps) => {\n /** Resolve any remaining {{t()}} or {{meta()}} template expressions in a string at render time. */\n const resolve = (text: string | undefined): string => {\n if (!text || (!t && !meta)) {\n return text || '';\n }\n return resolveFlowTemplateLiterals(text, {meta, t: t || ((k: string): string => k)});\n };\n\n const config: ConsentConfig = {...defaultConfig, ...suppliedConfig};\n const essentialInfo = typeof config.essentialInfo === 'string' ? resolve(config.essentialInfo.trim()) : '';\n const optionalInfo = typeof config.optionalInfo === 'string' ? resolve(config.optionalInfo.trim()) : '';\n const essentialLabel = resolve(config['essential']);\n const optionalLabel = resolve(config['optional']);\n\n /**\n * Method to check whether master toggle button is checked or not\n * @param purpose Purpose object\n * @param checked boolean variable to check, whether toggle is checked or unchecked\n */\n const handleChange = (purpose: ConsentPurposeData, checked: boolean): void => {\n const checkValue = checked ? 'true' : 'false';\n purpose.optional.map((opt: PromptElement) => {\n const key: string = getConsentOptionalKey(purpose.purposeId, opt.name);\n onInputChange(key, checkValue);\n });\n };\n\n /**\n * Check all optional claims are selected or not\n * @param purpose Purpose object\n * @returns boolean value to denote all optional claims are selected\n */\n const checkOptValue = (purpose: ConsentPurposeData): boolean => {\n return purpose.optional.every((opt: PromptElement) => {\n const key: string = getConsentOptionalKey(purpose.purposeId, opt.name);\n return formValues[key] === 'true';\n });\n };\n\n if (!consentData) return null;\n\n let purposes: ConsentPurposeData[] = [];\n\n try {\n const parsed: ConsentPurposeData[] | {purposes: ConsentPurposeData[]} =\n typeof consentData === 'string' ? JSON.parse(consentData) : consentData;\n\n purposes = Array.isArray(parsed) ? parsed : parsed.purposes || [];\n } catch (e) {\n // Failed to parse consent prompt data\n return null;\n }\n\n if (purposes.length === 0) return null;\n\n if (children) {\n return <>{children({formValues, onInputChange, purposes: purposes})}</>;\n }\n\n return (\n <div style={{display: 'flex', flexDirection: 'column', gap: '1rem', marginTop: '0.25rem'}}>\n {purposes.map((purpose: ConsentPurposeData, purposeIndex: number) => (\n <div key={purpose.purposeId || purposeIndex} style={{paddingBottom: '1rem'}}>\n {/* TODO: Uncomment when the backend supports multiple purposes for a application */}\n {/* <Typography variant=\"h6\" fontWeight={600} gutterBottom color=\"inherit\">\n {purpose.purposeName}\n </Typography>\n <Typography variant=\"body2\" color=\"inherit\" style={{marginBottom: '1rem', opacity: 0.85}}>\n {purpose.description}\n </Typography> */}\n\n {purpose.essential && purpose.essential.length > 0 && (\n <div style={{marginTop: '0.5rem'}}>\n <div style={{display: 'flex', alignItems: 'center', gap: '4px', marginBottom: '10px'}}>\n <Typography variant=\"subtitle2\" fontWeight=\"bold\">\n {essentialLabel}\n </Typography>\n {essentialInfo !== '' && (\n <Tooltip helperText={essentialInfo}>\n <Info width=\"1rem\" height=\"1rem\" />\n </Tooltip>\n )}\n </div>\n <ConsentCheckboxList\n variant=\"ESSENTIAL\"\n purpose={purpose}\n formValues={formValues}\n onInputChange={onInputChange}\n />\n </div>\n )}\n\n {purpose.optional && purpose.optional.length > 0 && (\n <div style={{marginTop: '0.5rem'}}>\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingRight: '4px',\n marginBottom: '10px',\n }}\n >\n <div style={{display: 'flex', alignItems: 'center', gap: '4px'}}>\n <Typography variant=\"subtitle2\" fontWeight=\"bold\">\n {purpose.type === 'permissions' ? 'Permissions' : optionalLabel}\n </Typography>\n {optionalInfo !== '' && (\n <Tooltip helperText={optionalInfo}>\n <Info width=\"1rem\" height=\"1rem\" />\n </Tooltip>\n )}\n </div>\n <Toggle\n id={`consent_opt_${purpose.purposeId}_all`}\n checked={checkOptValue(purpose)}\n aria-label=\"Toggle all optional attributes\"\n onChange={(e: ChangeEvent<HTMLInputElement>): void => handleChange(purpose, e.target.checked)}\n />\n </div>\n <ConsentCheckboxList\n variant=\"OPTIONAL\"\n purpose={purpose}\n formValues={formValues}\n onInputChange={onInputChange}\n />\n </div>\n )}\n </div>\n ))}\n </div>\n );\n};\n\nexport default Consent;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsentCheckboxList.d.ts","sourceRoot":"","sources":["../../../src/components/adapters/ConsentCheckboxList.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAC,KAAK,kBAAkB,EAAgC,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAmB,EAAE,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ConsentCheckboxList.d.ts","sourceRoot":"","sources":["../../../src/components/adapters/ConsentCheckboxList.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAC,KAAK,kBAAkB,EAAgC,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAmB,EAAE,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AAMtD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,MAAM,EAAE,UAAU,MAAM,KAAG,MAChC,CAAC;AAE7C;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG,UAAU,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,6CAA6C;IAC7C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;OAGG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3D;;;OAGG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,sEAAsE;IACtE,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,SAAS,CAAC;IAChE,iEAAiE;IACjE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,sEAAsE;IACtE,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,0DAA0D;IAC1D,OAAO,EAAE,kBAAkB,CAAC;IAC5B,iFAAiF;IACjF,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,QAAA,MAAM,mBAAmB,EAAE,EAAE,CAAC,wBAAwB,CAyFrD,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import useTheme_default from "../../contexts/Theme/useTheme.js";
|
|
2
2
|
import Typography_default from "../primitives/Typography/Typography.js";
|
|
3
3
|
import ConsentCheckboxList_styles_default from "./ConsentCheckboxList.styles.js";
|
|
4
|
-
import Divider_default from "../primitives/Divider/Divider.js";
|
|
5
4
|
import Toggle_default from "../primitives/Toggle/Toggle.js";
|
|
6
5
|
import { bem, withVendorCSSClassPrefix } from "@thunderid/browser";
|
|
7
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -31,7 +30,7 @@ const ConsentCheckboxList = ({ variant, purpose, formValues, onInputChange, chil
|
|
|
31
30
|
const isEssential = variant === "ESSENTIAL";
|
|
32
31
|
const isChecked = (attrName) => {
|
|
33
32
|
if (isEssential) return true;
|
|
34
|
-
return formValues[getConsentOptionalKey(purpose.purposeId, attrName)]
|
|
33
|
+
return formValues[getConsentOptionalKey(purpose.purposeId, attrName)] === "true";
|
|
35
34
|
};
|
|
36
35
|
const handleChange = (attrName, checked) => {
|
|
37
36
|
onInputChange(getConsentOptionalKey(purpose.purposeId, attrName), checked ? "true" : "false");
|
|
@@ -47,9 +46,9 @@ const ConsentCheckboxList = ({ variant, purpose, formValues, onInputChange, chil
|
|
|
47
46
|
children: attributes.map((attr) => {
|
|
48
47
|
const inputId = `consent_${isEssential ? "ess" : "opt"}_${purpose.purposeId}_${attr}`;
|
|
49
48
|
const checked = isChecked(attr);
|
|
50
|
-
return /* @__PURE__ */
|
|
49
|
+
return /* @__PURE__ */ jsx("div", {
|
|
51
50
|
className: cx(withVendorCSSClassPrefix(bem("consent-checkbox-list", "item")), styles["listItem"]),
|
|
52
|
-
children:
|
|
51
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
53
52
|
className: cx(withVendorCSSClassPrefix(bem("consent-checkbox-list", "row")), styles["listRow"]),
|
|
54
53
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
55
54
|
className: cx(withVendorCSSClassPrefix(bem("consent-checkbox-list", "label-container")), styles["labelContainer"]),
|
|
@@ -58,13 +57,16 @@ const ConsentCheckboxList = ({ variant, purpose, formValues, onInputChange, chil
|
|
|
58
57
|
className: cx(withVendorCSSClassPrefix(bem("consent-checkbox-list", "typography")), styles["typography"]),
|
|
59
58
|
children: attr
|
|
60
59
|
})]
|
|
61
|
-
}), /* @__PURE__ */ jsx(
|
|
60
|
+
}), isEssential ? /* @__PURE__ */ jsx(Typography_default, {
|
|
61
|
+
variant: "body2",
|
|
62
|
+
children: "Required"
|
|
63
|
+
}) : /* @__PURE__ */ jsx(Toggle_default, {
|
|
62
64
|
id: inputId,
|
|
63
65
|
checked,
|
|
64
66
|
disabled: isEssential,
|
|
65
67
|
onChange: isEssential ? void 0 : (e) => handleChange(attr, e.target.checked)
|
|
66
68
|
})]
|
|
67
|
-
})
|
|
69
|
+
})
|
|
68
70
|
}, attr);
|
|
69
71
|
})
|
|
70
72
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsentCheckboxList.js","names":["ConsentCheckboxList: FC<ConsentCheckboxListProps>","useTheme","styles: Record<string, string>","useStyles","attributes: string[]","isEssential: boolean","checked: boolean","Typography","Toggle"
|
|
1
|
+
{"version":3,"file":"ConsentCheckboxList.js","names":["ConsentCheckboxList: FC<ConsentCheckboxListProps>","useTheme","styles: Record<string, string>","useStyles","attributes: string[]","isEssential: boolean","checked: boolean","Typography","Toggle"],"sources":["../../../src/components/adapters/ConsentCheckboxList.tsx"],"sourcesContent":["/**\n * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {cx} from '@emotion/css';\nimport {type ConsentPurposeData, withVendorCSSClassPrefix, bem} from '@thunderid/browser';\nimport {type ChangeEvent, FC, ReactNode} from 'react';\nimport useStyles from './ConsentCheckboxList.styles';\nimport useTheme from '../../contexts/Theme/useTheme';\nimport Toggle from '../primitives/Toggle/Toggle';\nimport Typography from '../primitives/Typography/Typography';\n\n/**\n * Computes the form value key for tracking an optional attribute's consent state.\n *\n * @param purposeId - The ID of the consent purpose.\n * @param attrName - The name of the attribute.\n * @returns A stable form key string.\n */\nexport const getConsentOptionalKey = (purposeId: string, attrName: string): string =>\n `__consent_opt__${purposeId}__${attrName}`;\n\n/**\n * ConsentInputVariant defines whether the ConsentCheckboxList is rendering essential (read-only) or\n * optional (toggleable) attributes.\n */\nexport type ConsentInputVariant = 'ESSENTIAL' | 'OPTIONAL';\n\n/**\n * Render props exposed by ConsentCheckboxList when using the render-prop pattern.\n */\nexport interface ConsentCheckboxListRenderProps {\n /** The list of attribute names to render. */\n attributes: string[];\n /**\n * Call this when an optional attribute checkbox is toggled.\n * No-op for ESSENTIAL attributes (they cannot be changed).\n */\n handleChange: (attrName: string, checked: boolean) => void;\n /**\n * Returns the current checked state for the given attribute name.\n * Always returns true for ESSENTIAL attributes.\n */\n isChecked: (attrName: string) => boolean;\n /** Whether the list is rendering essential or optional attributes. */\n variant: ConsentInputVariant;\n}\n\n/**\n * Props for the ConsentCheckboxList component.\n */\nexport interface ConsentCheckboxListProps {\n /**\n * Render-props callback. When provided, the default checkbox list UI is replaced\n * with whatever JSX the callback returns.\n *\n * @example\n * ```tsx\n * <ConsentCheckboxList variant=\"OPTIONAL\" purpose={purpose} formValues={formValues} onInputChange={onChange}>\n * {({ attributes, isChecked, handleChange }) => (\n * <ul>\n * {attributes.map(attr => (\n * <li key={attr}>\n * <Checkbox checked={isChecked(attr)} onChange={e => handleChange(attr, e.target.checked)} />\n * {attr}\n * </li>\n * ))}\n * </ul>\n * )}\n * </ConsentCheckboxList>\n * ```\n */\n children?: (props: ConsentCheckboxListRenderProps) => ReactNode;\n /** Current form values - used to read optional checkbox state */\n formValues: Record<string, string>;\n /** Callback invoked when an optional attribute checkbox is toggled */\n onInputChange: (name: string, value: string) => void;\n /** The consent purpose data containing attribute lists */\n purpose: ConsentPurposeData;\n /** Whether to render essential (disabled) or optional (toggleable) attributes */\n variant: ConsentInputVariant;\n}\n\n/**\n * Renders a list of consent attribute checkboxes.\n *\n * - ESSENTIAL variant: renders read-only checked checkboxes for required attributes.\n * - OPTIONAL variant: renders toggleable checkboxes for optional attributes.\n * Opt-in is the default when no prior form value exists.\n */\nconst ConsentCheckboxList: FC<ConsentCheckboxListProps> = ({\n variant,\n purpose,\n formValues,\n onInputChange,\n children,\n}: ConsentCheckboxListProps) => {\n const {theme, colorScheme}: ReturnType<typeof useTheme> = useTheme();\n const styles: Record<string, string> = useStyles(theme, colorScheme);\n\n const attributes: string[] = (variant === 'ESSENTIAL' ? purpose.essential : purpose.optional).map(\n (e): string => e.name,\n );\n\n if (!attributes || attributes.length === 0) {\n return null;\n }\n\n const isEssential: boolean = variant === 'ESSENTIAL';\n\n const isChecked = (attrName: string): boolean => {\n if (isEssential) {\n return true;\n }\n const key: string = getConsentOptionalKey(purpose.purposeId, attrName);\n // Default to be false when there's no explicit form value\n return formValues[key] === 'true';\n };\n\n const handleChange = (attrName: string, checked: boolean): void => {\n const key: string = getConsentOptionalKey(purpose.purposeId, attrName);\n onInputChange(key, checked ? 'true' : 'false');\n };\n\n if (children) {\n return <>{children({attributes, handleChange, isChecked, variant})}</>;\n }\n\n return (\n <div className={cx(withVendorCSSClassPrefix(bem('consent-checkbox-list')), styles['listContainer'])}>\n {attributes.map((attr: string) => {\n const inputId = `consent_${isEssential ? 'ess' : 'opt'}_${purpose.purposeId}_${attr}`;\n const checked: boolean = isChecked(attr);\n\n return (\n <div\n key={attr}\n className={cx(withVendorCSSClassPrefix(bem('consent-checkbox-list', 'item')), styles['listItem'])}\n >\n <div className={cx(withVendorCSSClassPrefix(bem('consent-checkbox-list', 'row')), styles['listRow'])}>\n <div\n className={cx(\n withVendorCSSClassPrefix(bem('consent-checkbox-list', 'label-container')),\n styles['labelContainer'],\n )}\n >\n <div\n className={cx(withVendorCSSClassPrefix(bem('consent-checkbox-list', 'bullet')), styles['bullet'])}\n />\n <Typography\n variant=\"body2\"\n className={cx(\n withVendorCSSClassPrefix(bem('consent-checkbox-list', 'typography')),\n styles['typography'],\n )}\n >\n {attr}\n </Typography>\n </div>\n {isEssential ? (\n <Typography variant=\"body2\">Required</Typography>\n ) : (\n <Toggle\n id={inputId}\n checked={checked}\n disabled={isEssential}\n onChange={\n isEssential\n ? undefined\n : (e: ChangeEvent<HTMLInputElement>): void => handleChange(attr, e.target.checked)\n }\n />\n )}\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nexport default ConsentCheckboxList;\n"],"mappings":";;;;;;;;;;;;;;;;AAiCA,MAAa,yBAAyB,WAAmB,aACvD,kBAAkB,UAAU,IAAI;;;;;;;;AAsElC,MAAMA,uBAAqD,EACzD,SACA,SACA,YACA,eACA,eAC8B;CAC9B,MAAM,EAAC,OAAO,gBAA4CC,kBAAU;CACpE,MAAMC,SAAiCC,mCAAU,OAAO,YAAY;CAEpE,MAAMC,cAAwB,YAAY,cAAc,QAAQ,YAAY,QAAQ,UAAU,KAC3F,MAAc,EAAE,KAClB;AAED,KAAI,CAAC,cAAc,WAAW,WAAW,EACvC,QAAO;CAGT,MAAMC,cAAuB,YAAY;CAEzC,MAAM,aAAa,aAA8B;AAC/C,MAAI,YACF,QAAO;AAIT,SAAO,WAFa,sBAAsB,QAAQ,WAAW,SAAS,MAE3C;;CAG7B,MAAM,gBAAgB,UAAkB,YAA2B;AAEjE,gBADoB,sBAAsB,QAAQ,WAAW,SAAS,EACnD,UAAU,SAAS,QAAQ;;AAGhD,KAAI,SACF,QAAO,0CAAG,SAAS;EAAC;EAAY;EAAc;EAAW;EAAQ,CAAC,GAAI;AAGxE,QACE,oBAAC;EAAI,WAAW,GAAG,yBAAyB,IAAI,wBAAwB,CAAC,EAAE,OAAO,iBAAiB;YAChG,WAAW,KAAK,SAAiB;GAChC,MAAM,UAAU,WAAW,cAAc,QAAQ,MAAM,GAAG,QAAQ,UAAU,GAAG;GAC/E,MAAMC,UAAmB,UAAU,KAAK;AAExC,UACE,oBAAC;IAEC,WAAW,GAAG,yBAAyB,IAAI,yBAAyB,OAAO,CAAC,EAAE,OAAO,YAAY;cAEjG,qBAAC;KAAI,WAAW,GAAG,yBAAyB,IAAI,yBAAyB,MAAM,CAAC,EAAE,OAAO,WAAW;gBAClG,qBAAC;MACC,WAAW,GACT,yBAAyB,IAAI,yBAAyB,kBAAkB,CAAC,EACzE,OAAO,kBACR;iBAED,oBAAC,SACC,WAAW,GAAG,yBAAyB,IAAI,yBAAyB,SAAS,CAAC,EAAE,OAAO,UAAU,GACjG,EACF,oBAACC;OACC,SAAQ;OACR,WAAW,GACT,yBAAyB,IAAI,yBAAyB,aAAa,CAAC,EACpE,OAAO,cACR;iBAEA;QACU;OACT,EACL,cACC,oBAACA;MAAW,SAAQ;gBAAQ;OAAqB,GAEjD,oBAACC;MACC,IAAI;MACK;MACT,UAAU;MACV,UACE,cACI,UACC,MAA2C,aAAa,MAAM,EAAE,OAAO,QAAQ;OAEtF;MAEA;MArCD,KAsCD;IAER;GACE;;AAIV,kCAAe"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsentCheckboxList.styles.d.ts","sourceRoot":"","sources":["../../../src/components/adapters/ConsentCheckboxList.styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAGzC,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"ConsentCheckboxList.styles.d.ts","sourceRoot":"","sources":["../../../src/components/adapters/ConsentCheckboxList.styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAC,KAAK,EAAC,MAAM,oBAAoB,CAAC;AAGzC,QAAA,MAAM,SAAS,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAsCzE,CAAC;AAEJ,eAAe,SAAS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsentCheckboxList.styles.js","names":[],"sources":["../../../src/components/adapters/ConsentCheckboxList.styles.ts"],"sourcesContent":["/**\n * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {css} from '@emotion/css';\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\n\nconst useStyles = (theme: Theme, colorScheme: string): Record<string, string> =>\n useMemo(\n () => ({\n bullet: css`\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background-color: #9e9e9e;\n flex-shrink: 0;\n `,\n divider: css`\n opacity: 0.5;\n margin: 0.25rem 0;\n `,\n labelContainer: css`\n display: flex;\n align-items: center;\n gap: 0.4rem;\n `,\n listContainer: css`\n display: flex;\n flex-direction: column;\n `,\n listItem: css`\n padding: 0 0.25rem;\n `,\n listRow: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.125rem 0;\n `,\n typography: css`\n margin: 0;\n `,\n }),\n [theme, colorScheme],\n );\n\nexport default useStyles;\n"],"mappings":";;;;AAsBA,MAAM,aAAa,OAAc,gBAC/B,eACS;CACL,QAAQ,GAAG;;;;;;;CAOX,SAAS,GAAG;;;;CAIZ,gBAAgB,GAAG;;;;;CAKnB,eAAe,GAAG;;;;CAIlB,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"ConsentCheckboxList.styles.js","names":[],"sources":["../../../src/components/adapters/ConsentCheckboxList.styles.ts"],"sourcesContent":["/**\n * Copyright (c) 2026, WSO2 LLC. (https://www.wso2.com).\n *\n * WSO2 LLC. licenses this file to you under the Apache License,\n * Version 2.0 (the \"License\"); you may not use this file except\n * in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied. See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\nimport {css} from '@emotion/css';\nimport {Theme} from '@thunderid/browser';\nimport {useMemo} from 'react';\n\nconst useStyles = (theme: Theme, colorScheme: string): Record<string, string> =>\n useMemo(\n () => ({\n bullet: css`\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background-color: #9e9e9e;\n flex-shrink: 0;\n `,\n divider: css`\n opacity: 0.5;\n margin: 0.25rem 0;\n `,\n labelContainer: css`\n display: flex;\n align-items: center;\n gap: 0.4rem;\n `,\n listContainer: css`\n display: flex;\n flex-direction: column;\n `,\n listItem: css`\n padding: 0 0.25rem;\n margin-bottom: 4px;\n `,\n listRow: css`\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.125rem 0;\n `,\n typography: css`\n margin: 0;\n `,\n }),\n [theme, colorScheme],\n );\n\nexport default useStyles;\n"],"mappings":";;;;AAsBA,MAAM,aAAa,OAAc,gBAC/B,eACS;CACL,QAAQ,GAAG;;;;;;;CAOX,SAAS,GAAG;;;;CAIZ,gBAAgB,GAAG;;;;;CAKnB,eAAe,GAAG;;;;CAIlB,UAAU,GAAG;;;;CAIb,SAAS,GAAG;;;;;;CAMZ,YAAY,GAAG;;;CAGhB,GACD,CAAC,OAAO,YAAY,CACrB;AAEH,yCAAe"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import useTheme_default from "../../../contexts/Theme/useTheme.js";
|
|
2
2
|
import Button_default from "../../primitives/Button/Button.js";
|
|
3
3
|
import Typography_default from "../../primitives/Typography/Typography.js";
|
|
4
|
+
import LogOut_default from "../../primitives/Icons/LogOut.js";
|
|
5
|
+
import User_default from "../../primitives/Icons/User.js";
|
|
4
6
|
import getMappedUserProfileValue_default from "../../../utils/getMappedUserProfileValue.js";
|
|
5
7
|
import getDisplayName_default from "../../../utils/getDisplayName.js";
|
|
6
8
|
import { Avatar } from "../../primitives/Avatar/Avatar.js";
|
|
7
|
-
import LogOut_default from "../../primitives/Icons/LogOut.js";
|
|
8
|
-
import User_default from "../../primitives/Icons/User.js";
|
|
9
9
|
import BaseUserDropdown_styles_default from "./BaseUserDropdown.styles.js";
|
|
10
10
|
import { withVendorCSSClassPrefix } from "@thunderid/browser";
|
|
11
11
|
import { useState } from "react";
|
|
@@ -4,10 +4,10 @@ import Button_default from "../../primitives/Button/Button.js";
|
|
|
4
4
|
import Typography_default from "../../primitives/Typography/Typography.js";
|
|
5
5
|
import Alert_default from "../../primitives/Alert/Alert.js";
|
|
6
6
|
import Card_default from "../../primitives/Card/Card.js";
|
|
7
|
-
import Divider_default from "../../primitives/Divider/Divider.js";
|
|
8
7
|
import Checkbox_default from "../../primitives/Checkbox/Checkbox.js";
|
|
9
8
|
import DatePicker_default from "../../primitives/DatePicker/DatePicker.js";
|
|
10
9
|
import TextField_default from "../../primitives/TextField/TextField.js";
|
|
10
|
+
import Divider_default from "../../primitives/Divider/Divider.js";
|
|
11
11
|
import BaseUserProfile_styles_default from "./BaseUserProfile.styles.js";
|
|
12
12
|
import getMappedUserProfileValue_default from "../../../utils/getMappedUserProfileValue.js";
|
|
13
13
|
import getDisplayName_default from "../../../utils/getDisplayName.js";
|