-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathsso-provider-create.json
More file actions
458 lines (458 loc) · 260 KB
/
Copy pathsso-provider-create.json
File metadata and controls
458 lines (458 loc) · 260 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "my-organization/sso-provider-create",
"type": "registry:block",
"title": "SSO Provider Creation Wizard",
"description": "A multi-step wizard for creating SSO identity providers with support for multiple strategies including SAMLP, OIDC, ADFS, Okta, Google Workspace, Azure AD, and PingFederate.",
"dependencies": [
"sonner",
"react-hook-form",
"@hookform/resolvers",
"clsx",
"tailwind-merge",
"class-variance-authority",
"lucide-react",
"next-themes",
"@radix-ui/react-accordion",
"@radix-ui/react-checkbox",
"@radix-ui/react-label",
"@radix-ui/react-radio-group",
"@radix-ui/react-slot",
"@radix-ui/react-switch",
"@radix-ui/react-tooltip"
],
"files": [
{
"path": "src/blocks/my-organization/idp-management/sso-provider-create.tsx",
"content": "import {\n getComponentStyles,\n type IdpStrategy,\n type ProviderDetailsFormValues,\n type ProviderConfigureFormValues,\n MY_ORGANIZATION_SSO_PROVIDER_CREATE_SCOPES,\n} from '@auth0/universal-components-core';\nimport React, { useState, useRef, useCallback, useMemo } from 'react';\n\nimport ProviderConfigure, {\n type ProviderConfigureHandle,\n} from '../../../components/my-organization/idp-management/sso-provider-create/provider-configure/provider-configure';\nimport {\n ProviderDetails,\n type ProviderDetailsFormHandle,\n} from '../../../components/my-organization/idp-management/sso-provider-create/provider-details';\nimport { ProviderSelect } from '../../../components/my-organization/idp-management/sso-provider-create/provider-select';\nimport { Header } from '../../../components/ui/header';\nimport { Wizard } from '../../../components/ui/wizard';\nimport type { StepProps } from '../../../components/ui/wizard';\nimport { withMyOrganizationService } from '../../../hoc/with-services';\nimport { useConfig } from '../../../hooks/my-organization/config/use-config';\nimport { useIdpConfig } from '../../../hooks/my-organization/config/use-idp-config';\nimport { useSsoProviderCreate } from '../../../hooks/my-organization/idp-management/use-sso-provider-create';\nimport { useTheme } from '../../../hooks/use-theme';\nimport { useTranslator } from '../../../hooks/use-translator';\nimport type { SsoProviderCreateProps } from '../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\n\ntype FormState = {\n strategy?: IdpStrategy;\n details?: ProviderDetailsFormValues | null;\n configure?: ProviderConfigureFormValues | null;\n};\n\nexport function SsoProviderCreateComponent({\n createAction,\n backButton,\n onNext,\n onPrevious,\n customMessages = {},\n styling = {\n variables: { common: {}, light: {}, dark: {} },\n classes: {},\n },\n}: SsoProviderCreateProps) {\n const { t } = useTranslator('idp_management.create_sso_provider', customMessages);\n const { isDarkMode } = useTheme();\n\n const [formData, setFormData] = useState<FormState>({});\n const { strategy, details, configure } = formData;\n\n const { createProvider, isCreating } = useSsoProviderCreate({\n createAction,\n customMessages,\n });\n const { isLoadingConfig, filteredStrategies } = useConfig();\n const { isLoadingIdpConfig, idpConfig } = useIdpConfig();\n\n const detailsRef = useRef<ProviderDetailsFormHandle>(null);\n const configureRef = useRef<ProviderConfigureHandle>(null);\n\n const currentStyles = useMemo(\n () => getComponentStyles(styling, isDarkMode),\n [styling, isDarkMode],\n );\n\n const createStepActions = useCallback(\n (\n stepId: 'provider_details' | 'provider_configure',\n ref: React.RefObject<ProviderDetailsFormHandle | ProviderConfigureHandle | null>,\n ) => {\n const dataKey = stepId === 'provider_details' ? 'details' : 'configure';\n\n const handleAction = async (\n handler: typeof onNext | typeof onPrevious | undefined,\n shouldValidate = false,\n ): Promise<boolean> => {\n if (shouldValidate) {\n const isValid = await ref.current?.validate();\n if (!isValid) return false;\n }\n\n const currentData = ref.current?.getData() ?? null;\n setFormData((prev) => ({ ...prev, [dataKey]: currentData }));\n if (!handler) return true;\n const fullPayload = { ...formData, [dataKey]: currentData };\n return handler(stepId, fullPayload);\n };\n\n return {\n onNextAction: () => handleAction(onNext, true),\n onPreviousAction: () => handleAction(onPrevious, false),\n };\n },\n [formData, onNext, onPrevious],\n );\n\n const handleCreate = useCallback(async () => {\n const finalConfigureData = configureRef.current?.getData();\n\n await createProvider({\n strategy: strategy!,\n ...details!,\n ...finalConfigureData,\n });\n }, [strategy, details, configure, createProvider]);\n\n const wizardSteps = useMemo(\n () => [\n {\n id: 'provider_select',\n title: t('steps.one'),\n content: ({ onNext: navigate }: StepProps) => (\n <ProviderSelect\n isLoading={isLoadingConfig}\n strategyList={filteredStrategies}\n onClickStrategy={(selected) => {\n setFormData((prev) => ({\n strategy: selected,\n details: prev.strategy === selected ? prev.details : null,\n configure: prev.strategy === selected ? prev.configure : null,\n }));\n\n onNext?.('provider_select', { strategy: selected });\n navigate?.();\n }}\n selectedStrategy={strategy}\n customMessages={customMessages.provider_select}\n className={currentStyles?.classes?.['ProviderSelect-root']}\n />\n ),\n actions: {\n showNext: false,\n },\n },\n {\n id: 'provider_details',\n title: t('steps.two'),\n content: () => (\n <ProviderDetails\n mode=\"create\"\n ref={detailsRef}\n initialData={details ?? undefined}\n customMessages={customMessages.provider_details}\n styling={styling}\n className={currentStyles?.classes?.['ProviderDetails-root']}\n />\n ),\n actions: createStepActions('provider_details', detailsRef),\n },\n {\n id: 'provider_configure',\n title: t('steps.three'),\n content: () =>\n strategy ? (\n <ProviderConfigure\n ref={configureRef}\n strategy={strategy}\n isLoading={isLoadingIdpConfig}\n initialData={configure ?? undefined}\n customMessages={customMessages.provider_configure}\n idpConfig={idpConfig}\n className={currentStyles?.classes?.['ProviderConfigure-root']}\n />\n ) : null,\n actions: createStepActions('provider_configure', configureRef),\n },\n ],\n [\n t,\n strategy,\n details,\n configure,\n onNext,\n onPrevious,\n customMessages,\n currentStyles,\n styling,\n createStepActions,\n ],\n );\n\n return (\n <div style={currentStyles.variables} className=\"w-full\">\n <Header\n title={t('header.title')}\n backButton={\n backButton && {\n ...backButton,\n text: t('header.back_button_text'),\n }\n }\n className={currentStyles?.classes?.['SsoProviderCreate-header']}\n />\n <div className=\"sso-provider-create__content\" data-testid=\"sso-provider-create-content\">\n <Wizard\n isLoading={isCreating}\n hideStepperNumbers\n steps={wizardSteps}\n onComplete={handleCreate}\n formActionLabels={{\n nextButtonLabel: t('nextButtonLabel'),\n previousButtonLabel: t('previousButtonLabel'),\n completeButtonLabel: t('completeButtonLabel'),\n }}\n className={currentStyles?.classes?.['SsoProviderCreate-wizard']}\n />\n </div>\n </div>\n );\n}\n\nexport const SsoProviderCreate = withMyOrganizationService(\n SsoProviderCreateComponent,\n MY_ORGANIZATION_SSO_PROVIDER_CREATE_SCOPES,\n);\n",
"type": "registry:block",
"target": "auth0-ui-components/blocks/my-organization/idp-management/sso-provider-create.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-select.tsx",
"content": "import type { IdpStrategy } from '@auth0/universal-components-core';\nimport { STRATEGY_DISPLAY_NAMES, STRATEGIES } from '@auth0/universal-components-core';\nimport React from 'react';\n\nimport EntraIdLogo from '../../../../assets/icons/entraid-logo';\nimport GoogleLogo from '../../../../assets/icons/google-logo';\nimport MicrosoftLogo from '../../../../assets/icons/microsoft-logo';\nimport OidcLogo from '../../../../assets/icons/oidc-logo';\nimport OktaLogo from '../../../../assets/icons/okta-logo';\nimport PingIdLogo from '../../../../assets/icons/pingid-logo';\nimport SamlpLogo from '../../../../assets/icons/sampl-logo';\nimport { Button } from '../../../../components/ui/button';\nimport { Section } from '../../../../components/ui/section';\nimport { Spinner } from '../../../../components/ui/spinner';\nimport { useTranslator } from '../../../../hooks/use-translator';\nimport type { ProviderSelectProps } from '../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\n\nconst STRATEGY_ICONS: Record<IdpStrategy, React.FC<{ className?: string }>> = {\n [STRATEGIES.OKTA]: OktaLogo,\n [STRATEGIES.GOOGLE_APPS]: GoogleLogo,\n [STRATEGIES.WAAD]: EntraIdLogo,\n [STRATEGIES.ADFS]: MicrosoftLogo,\n [STRATEGIES.PINGFEDERATE]: PingIdLogo,\n [STRATEGIES.SAMLP]: SamlpLogo,\n [STRATEGIES.OIDC]: OidcLogo,\n};\n\nfunction ProviderSelect({\n isLoading,\n strategyList,\n onClickStrategy,\n customMessages = {},\n className,\n}: ProviderSelectProps) {\n const { t } = useTranslator('idp_management.create_sso_provider.provider_select', customMessages);\n\n return (\n <Section title={t('title')} description={t('description')} className={className}>\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {isLoading ? (\n <div className=\"col-span-full flex items-center justify-center min-h-[100px]\">\n <Spinner />\n </div>\n ) : (\n strategyList.map((strategyType) => {\n const IconComponent = STRATEGY_ICONS[strategyType as IdpStrategy];\n const displayName = STRATEGY_DISPLAY_NAMES[strategyType as IdpStrategy];\n return (\n <Button\n key={strategyType}\n variant=\"outline\"\n className=\"justify-start h-10 py-2.5 px-3\"\n onClick={() => onClickStrategy(strategyType)}\n >\n <div className=\"flex items-center gap-3 w-full text-left\">\n <IconComponent className=\"w-4 h-4 flex-shrink-0 text-primary\" />\n <div className=\"flex flex-col gap-1\">\n <span className=\"font-medium\">{displayName}</span>\n </div>\n </div>\n </Button>\n );\n })\n )}\n </div>\n </Section>\n );\n}\n\nexport { ProviderSelect };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-select.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-details.tsx",
"content": "import {\n createProviderDetailsSchema,\n type ProviderDetailsFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useTranslator } from '../../../../hooks/use-translator';\nimport type { ProviderDetailsProps } from '../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport {\n Form,\n FormControl,\n FormDescription,\n FormField,\n FormItem,\n FormLabel,\n FormMessage,\n} from '../../../ui/form';\nimport { Section } from '../../../ui/section';\nimport { TextField } from '../../../ui/text-field';\n\nexport interface ProviderDetailsFormHandle {\n validate: () => Promise<boolean>;\n getData: () => ProviderDetailsFormValues;\n isDirty: () => boolean;\n reset: (data?: ProviderDetailsFormValues) => void;\n}\n\nexport const ProviderDetails = React.forwardRef<ProviderDetailsFormHandle, ProviderDetailsProps>(\n function ProviderDetails(\n { initialData, mode, readOnly = false, customMessages = {}, className, onFormDirty },\n ref,\n ) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_details',\n customMessages,\n );\n\n const form = useForm<ProviderDetailsFormValues>({\n resolver: zodResolver(createProviderDetailsSchema()),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n name: initialData?.name || '',\n display_name: initialData?.display_name || '',\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n return (\n <Form {...form}>\n <div className={className}>\n <Section title={t('title')} description={t('description')}>\n <FormField\n control={form.control}\n name=\"name\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm text-(length:--font-size-label) font-medium\">\n {t('fields.name.label')}\n </FormLabel>\n <FormControl>\n <TextField\n placeholder={t('fields.name.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={mode === 'edit' ? true : readOnly}\n {...field}\n />\n </FormControl>\n <FormMessage\n className=\"text-left text-sm text-(length:--font-size-paragraph)\"\n role=\"alert\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.name.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"display_name\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm text-(length:--font-size-label) font-medium\">\n {t('fields.display_name.label')}\n </FormLabel>\n <FormControl>\n <TextField\n placeholder={t('fields.display_name.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n {...field}\n />\n </FormControl>\n <FormMessage\n className=\"text-left text-sm text-(length:--font-size-paragraph)\"\n role=\"alert\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.display_name.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n </Section>\n </div>\n </Form>\n );\n },\n);\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-details.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/provider-configure.tsx",
"content": "import type { ProviderConfigureFormValues } from '@auth0/universal-components-core';\nimport * as React from 'react';\n\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport type { ProviderConfigureProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport { Section } from '../../../../ui/section';\nimport { Spinner } from '../../../../ui/spinner';\n\nimport {\n ProviderConfigureFields,\n type ProviderConfigureFormHandle,\n} from './provider-configure-fields';\n\nexport interface ProviderConfigureHandle {\n validate: () => Promise<boolean>;\n getData: () => ProviderConfigureFormValues;\n}\n\nexport const ProviderConfigure = React.forwardRef<ProviderConfigureHandle, ProviderConfigureProps>(\n function ProviderConfigure(\n {\n strategy,\n initialData,\n readOnly = false,\n customMessages = {},\n className,\n idpConfig,\n isLoading,\n },\n ref,\n ) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const formRef = React.useRef<ProviderConfigureFormHandle>(null);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return (await formRef.current?.validate()) ?? false;\n },\n getData: () => {\n return formRef.current?.getData() as ProviderConfigureFormValues;\n },\n }));\n\n if (isLoading) {\n return (\n <div className=\"flex justify-center items-center p-8\">\n <Spinner />\n </div>\n );\n }\n\n return (\n <div className={className}>\n <Section title={t('title')} description={t('description')}>\n <ProviderConfigureFields\n ref={formRef}\n strategy={strategy}\n initialData={initialData}\n readOnly={readOnly}\n customMessages={customMessages.fields}\n idpConfig={idpConfig}\n />\n </Section>\n </div>\n );\n },\n);\n\nexport default ProviderConfigure;\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/provider-configure.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/provider-configure-fields.tsx",
"content": "import { STRATEGIES } from '@auth0/universal-components-core';\nimport * as React from 'react';\n\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\n\nimport { AdfsProviderForm, type AdfsConfigureFormHandle } from './adfs-sso-configure-form';\nimport {\n GoogleAppsProviderForm,\n type GoogleAppsConfigureFormHandle,\n} from './google-apps-sso-configure-form';\nimport { OidcProviderForm, type OidcConfigureFormHandle } from './oidc-sso-configure-form';\nimport { OktaProviderForm, type OktaConfigureFormHandle } from './okta-sso-configure-form';\nimport {\n PingFederateProviderForm,\n type PingFederateConfigureFormHandle,\n} from './ping-federate-sso-configure-form';\nimport { SamlpProviderForm, type SamlpConfigureFormHandle } from './samlp-sso-configure-form';\nimport { WaadProviderForm, type WaadConfigureFormHandle } from './waad-sso-configure-form';\n\nexport type ProviderConfigureFormHandle =\n | OktaConfigureFormHandle\n | GoogleAppsConfigureFormHandle\n | WaadConfigureFormHandle\n | PingFederateConfigureFormHandle\n | AdfsConfigureFormHandle\n | SamlpConfigureFormHandle\n | OidcConfigureFormHandle;\n\nexport const ProviderConfigureFields = React.forwardRef<\n ProviderConfigureFormHandle,\n ProviderConfigureFieldsProps\n>(function ProviderConfigureFields({ strategy, className, ...props }, ref) {\n const renderProviderForm = () => {\n switch (strategy) {\n case STRATEGIES.OKTA:\n return (\n <OktaProviderForm ref={ref as React.ForwardedRef<OktaConfigureFormHandle>} {...props} />\n );\n case STRATEGIES.GOOGLE_APPS:\n return (\n <GoogleAppsProviderForm\n ref={ref as React.ForwardedRef<GoogleAppsConfigureFormHandle>}\n {...props}\n />\n );\n case STRATEGIES.WAAD:\n return (\n <WaadProviderForm ref={ref as React.ForwardedRef<WaadConfigureFormHandle>} {...props} />\n );\n case STRATEGIES.PINGFEDERATE:\n return (\n <PingFederateProviderForm\n ref={ref as React.ForwardedRef<PingFederateConfigureFormHandle>}\n {...props}\n />\n );\n case STRATEGIES.ADFS:\n return (\n <AdfsProviderForm ref={ref as React.ForwardedRef<AdfsConfigureFormHandle>} {...props} />\n );\n case STRATEGIES.SAMLP:\n return (\n <SamlpProviderForm ref={ref as React.ForwardedRef<SamlpConfigureFormHandle>} {...props} />\n );\n case STRATEGIES.OIDC:\n return (\n <OidcProviderForm ref={ref as React.ForwardedRef<OidcConfigureFormHandle>} {...props} />\n );\n default:\n return null;\n }\n };\n\n return <div className={cn('space-y-6', className)}>{renderProviderForm()}</div>;\n});\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/provider-configure-fields.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/adfs-sso-configure-form.tsx",
"content": "import {\n createProviderConfigureSchema,\n type AdfsConfigureFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useState } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport { CopyableTextField } from '../../../../ui/copyable-text-field';\nimport { FileUpload } from '../../../../ui/file-upload';\nimport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n} from '../../../../ui/form';\nimport { Label } from '../../../../ui/label';\nimport { RadioGroup, RadioGroupItem } from '../../../../ui/radio-group';\nimport { TextField } from '../../../../ui/text-field';\n\nimport { CommonConfigureFields } from './common-configure-fields';\n\nexport interface AdfsConfigureFormHandle {\n validate: () => Promise<boolean>;\n getData: () => AdfsConfigureFormValues;\n isDirty: () => boolean;\n reset: (data?: AdfsConfigureFormValues) => void;\n}\n\ninterface AdfsConfigureFormProps extends Omit<ProviderConfigureFieldsProps, 'strategy'> {}\n\nexport const AdfsProviderForm = React.forwardRef<AdfsConfigureFormHandle, AdfsConfigureFormProps>(\n function AdfsProviderForm(\n { initialData, readOnly = false, customMessages = {}, className, onFormDirty, idpConfig },\n ref,\n ) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);\n\n const adfsData = initialData as AdfsConfigureFormValues | undefined;\n\n const form = useForm<AdfsConfigureFormValues>({\n resolver: zodResolver(createProviderConfigureSchema('adfs')),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n meta_data_source: adfsData?.meta_data_source || 'meta_data_url',\n meta_data_location_url: adfsData?.meta_data_location_url || '',\n adfs_server: adfsData?.adfs_server || '',\n fedMetadataXml: adfsData?.fedMetadataXml || '',\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n const typeValue = form.watch('meta_data_source');\n const showFederationMetadataFile = typeValue === 'meta_data_file';\n\n const handleFileUpload = async (files: File[]) => {\n setUploadedFiles(files);\n\n const file = files[0];\n if (file) {\n try {\n const content = await file.text();\n form.setValue('fedMetadataXml', content);\n } catch (error) {\n console.error('Error reading file:', error);\n }\n }\n };\n\n return (\n <Form {...form}>\n <div className={cn('space-y-6', className)}>\n <FormField\n control={form.control}\n name=\"meta_data_source\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.adfs.meta_data_source.label')}\n </FormLabel>\n <FormControl>\n <RadioGroup\n value={field.value}\n onValueChange={field.onChange}\n disabled={readOnly}\n className=\"flex flex-col space-y-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"meta_data_url\" id=\"meta_data_url\" />\n <Label htmlFor=\"meta_data_url\" className=\"text-sm font-normal cursor-pointer\">\n {t('fields.adfs.meta_data_source.options.meta_data_url.label')}\n </Label>\n </div>\n <div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"meta_data_file\" id=\"meta_data_file\" />\n <Label\n htmlFor=\"meta_data_file\"\n className=\"text-sm font-normal cursor-pointer\"\n >\n {t('fields.adfs.meta_data_source.options.meta_data_file.label')}\n </Label>\n </div>\n </RadioGroup>\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n\n {typeValue === 'meta_data_url' && (\n <>\n <FormField\n control={form.control}\n name=\"adfs_server\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.adfs.meta_data_url.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"url\"\n placeholder={t('fields.adfs.meta_data_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n aria-required={true}\n aria-invalid={Boolean(fieldState.error)}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.adfs.meta_data_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"meta_data_location_url\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.adfs.meta_data_location_url.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"url\"\n placeholder={t('fields.adfs.meta_data_location_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.adfs.meta_data_location_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n </>\n )}\n\n {showFederationMetadataFile && (\n <FormField\n control={form.control}\n name=\"fedMetadataXml\"\n render={() => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.adfs.federation_metadata_file.label')}\n </FormLabel>\n <FormControl>\n <div className=\"space-y-3\">\n <FileUpload\n accept=\".xml\"\n onChange={handleFileUpload}\n value={uploadedFiles}\n maxFiles={1}\n disabled={readOnly}\n className=\"w-full\"\n placeholder={t('fields.adfs.federation_metadata_file.placeholder')}\n />\n </div>\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.adfs.federation_metadata_file.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n )}\n\n <CommonConfigureFields\n idpConfig={idpConfig}\n readOnly={readOnly}\n customMessages={customMessages}\n />\n </div>\n </Form>\n );\n },\n);\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/adfs-sso-configure-form.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/google-apps-sso-configure-form.tsx",
"content": "import {\n createProviderConfigureSchema,\n type GoogleAppsConfigureFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useProviderFormMode } from '../../../../../hooks/my-organization/idp-management/use-provider-form-mode';\nimport { useCoreClient } from '../../../../../hooks/use-core-client';\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport { CopyableTextField } from '../../../../ui/copyable-text-field';\nimport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n} from '../../../../ui/form';\nimport { TextField } from '../../../../ui/text-field';\n\nimport { CommonConfigureFields } from './common-configure-fields';\n\nexport interface GoogleAppsConfigureFormHandle {\n validate: () => Promise<boolean>;\n getData: () => GoogleAppsConfigureFormValues;\n isDirty: () => boolean;\n reset: (data?: GoogleAppsConfigureFormValues) => void;\n}\n\ninterface GoogleAppsConfigureFormProps extends Omit<ProviderConfigureFieldsProps, 'strategy'> {}\n\nexport const GoogleAppsProviderForm = React.forwardRef<\n GoogleAppsConfigureFormHandle,\n GoogleAppsConfigureFormProps\n>(function GoogleAppsProviderForm(\n {\n initialData,\n readOnly = false,\n customMessages = {},\n className,\n onFormDirty,\n idpConfig,\n mode = 'create',\n },\n ref,\n) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const { coreClient } = useCoreClient();\n const { showCopyButtons } = useProviderFormMode(mode);\n\n const callbackUrl = React.useMemo(() => {\n const domain = coreClient?.auth?.domain || 'YOUR_DOMAIN';\n return `https://${domain}/login/callback`;\n }, [coreClient?.auth?.domain]);\n\n const googleAppsData = initialData as GoogleAppsConfigureFormValues | undefined;\n\n const form = useForm<GoogleAppsConfigureFormValues>({\n resolver: zodResolver(createProviderConfigureSchema('google-apps')),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n domain: googleAppsData?.domain || '',\n client_id: googleAppsData?.client_id || '',\n client_secret: googleAppsData?.client_secret || '',\n callback_url: callbackUrl || '',\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n return (\n <Form {...form}>\n <div className={cn('space-y-6', className)}>\n <FormField\n control={form.control}\n name=\"domain\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.google-apps.domain.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"text\"\n placeholder={t('fields.google-apps.domain.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"client_id\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.google-apps.client_id.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"text\"\n placeholder={t('fields.google-apps.client_id.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.google-apps.client_id.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"client_secret\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.google-apps.client_secret.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"password\"\n placeholder={t('fields.google-apps.client_secret.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.google-apps.client_secret.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"callback_url\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.google-apps.callback_url.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"text\"\n placeholder={t('fields.google-apps.callback_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={true}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.google-apps.callback_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <CommonConfigureFields\n idpConfig={idpConfig}\n readOnly={readOnly}\n customMessages={customMessages}\n />\n </div>\n </Form>\n );\n});\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/google-apps-sso-configure-form.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/oidc-sso-configure-form.tsx",
"content": "import {\n createProviderConfigureSchema,\n type OidcConfigureFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useProviderFormMode } from '../../../../../hooks/my-organization/idp-management/use-provider-form-mode';\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport { CopyableTextField } from '../../../../ui/copyable-text-field';\nimport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n} from '../../../../ui/form';\nimport { Label } from '../../../../ui/label';\nimport { RadioGroup, RadioGroupItem } from '../../../../ui/radio-group';\nimport { TextField } from '../../../../ui/text-field';\n\nimport { CommonConfigureFields } from './common-configure-fields';\n\nexport interface OidcConfigureFormHandle {\n validate: () => Promise<boolean>;\n getData: () => OidcConfigureFormValues;\n isDirty: () => boolean;\n reset: (data?: OidcConfigureFormValues) => void;\n}\n\ninterface OidcConfigureFormProps extends Omit<ProviderConfigureFieldsProps, 'strategy'> {}\n\nexport const OidcProviderForm = React.forwardRef<OidcConfigureFormHandle, OidcConfigureFormProps>(\n function OidcProviderForm(\n {\n initialData,\n readOnly = false,\n customMessages = {},\n className,\n onFormDirty,\n idpConfig,\n mode = 'create',\n },\n ref,\n ) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const { showCopyButtons } = useProviderFormMode(mode);\n\n const oidcData = initialData as OidcConfigureFormValues | undefined;\n\n const form = useForm<OidcConfigureFormValues>({\n resolver: zodResolver(createProviderConfigureSchema('oidc')),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n discovery_url: oidcData?.discovery_url || '',\n type: oidcData?.type || 'back_channel',\n client_id: oidcData?.client_id || '',\n client_secret: oidcData?.client_secret || '',\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n const typeValue = form.watch('type');\n const showClientSecret = typeValue === 'back_channel';\n\n // Clear client_secret error and value when switching to front channel\n React.useEffect(() => {\n if (typeValue === 'front_channel') {\n form.clearErrors('client_secret');\n form.setValue('client_secret', '', { shouldValidate: false });\n }\n }, [typeValue, form]);\n\n return (\n <Form {...form}>\n <div className={cn('space-y-6', className)}>\n <FormField\n control={form.control}\n name=\"discovery_url\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.oidc.discovery_url.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"url\"\n placeholder={t('fields.oidc.discovery_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n aria-required={true}\n aria-invalid={Boolean(fieldState.error)}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.oidc.discovery_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"type\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.oidc.type.label')}\n </FormLabel>\n <FormControl>\n <RadioGroup\n value={field.value}\n onValueChange={field.onChange}\n disabled={readOnly}\n className=\"flex flex-col space-y-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"back_channel\" id=\"back_channel\" />\n <Label htmlFor=\"back_channel\" className=\"text-sm font-normal cursor-pointer\">\n {t('fields.oidc.type.options.back_channel.label')}\n </Label>\n </div>\n <div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"front_channel\" id=\"front_channel\" />\n <Label htmlFor=\"front_channel\" className=\"text-sm font-normal cursor-pointer\">\n {t('fields.oidc.type.options.front_channel.label')}\n </Label>\n </div>\n </RadioGroup>\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.oidc.type.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"client_id\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.oidc.client_id.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"text\"\n placeholder={t('fields.oidc.client_id.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n aria-required={true}\n aria-invalid={Boolean(fieldState.error)}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.oidc.client_id.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n {showClientSecret && (\n <FormField\n control={form.control}\n name=\"client_secret\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.oidc.client_secret.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"password\"\n placeholder={t('fields.oidc.client_secret.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n aria-required={true}\n aria-invalid={Boolean(fieldState.error)}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.oidc.client_secret.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n )}\n\n <CommonConfigureFields\n idpConfig={idpConfig}\n readOnly={readOnly}\n customMessages={customMessages}\n />\n </div>\n </Form>\n );\n },\n);\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/oidc-sso-configure-form.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/okta-sso-configure-form.tsx",
"content": "import {\n createProviderConfigureSchema,\n type OktaConfigureFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useProviderFormMode } from '../../../../../hooks/my-organization/idp-management/use-provider-form-mode';\nimport { useCoreClient } from '../../../../../hooks/use-core-client';\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport { CopyableTextField } from '../../../../ui/copyable-text-field';\nimport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n} from '../../../../ui/form';\nimport { Link } from '../../../../ui/link';\nimport { TextField } from '../../../../ui/text-field';\n\nimport { CommonConfigureFields } from './common-configure-fields';\n\nconst OKTA_HELP_LINKS = {\n domain: 'https://developer.okta.com/docs/guides/find-your-domain/main/',\n client_id: 'https://developer.okta.com/docs/guides/find-your-app-credentials/main',\n client_secret: 'https://developer.okta.com/docs/guides/find-your-app-credentials/main',\n} as const;\n\nexport interface OktaConfigureFormHandle {\n validate: () => Promise<boolean>;\n getData: () => OktaConfigureFormValues;\n isDirty: () => boolean;\n reset: (data?: OktaConfigureFormValues) => void;\n}\n\ninterface OktaConfigureFormProps extends Omit<ProviderConfigureFieldsProps, 'strategy'> {}\n\nexport const OktaProviderForm = React.forwardRef<OktaConfigureFormHandle, OktaConfigureFormProps>(\n function OktaProviderForm(\n {\n initialData,\n readOnly = false,\n customMessages = {},\n className,\n onFormDirty,\n idpConfig,\n mode = 'create',\n },\n ref,\n ) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const { coreClient } = useCoreClient();\n const { showCopyButtons } = useProviderFormMode(mode);\n\n const callbackUrl = React.useMemo(() => {\n const domain = coreClient?.auth?.domain || 'YOUR_DOMAIN';\n return `https://${domain}/login/callback`;\n }, [coreClient?.auth?.domain]);\n\n const oktaData = initialData as OktaConfigureFormValues | undefined;\n\n const form = useForm<OktaConfigureFormValues>({\n resolver: zodResolver(createProviderConfigureSchema('okta')),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n domain: oktaData?.domain || '',\n client_id: oktaData?.client_id || '',\n client_secret: oktaData?.client_secret || '',\n icon_url: oktaData?.icon_url || '',\n callback_url: oktaData?.callback_url || callbackUrl,\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n return (\n <Form {...form}>\n <div className={cn('space-y-6', className)}>\n <FormField\n control={form.control}\n name=\"domain\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.okta.domain.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"text\"\n placeholder={t('fields.okta.domain.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n <>\n {t.trans('fields.okta.domain.helper_text', {\n components: {\n link: (children: string) => (\n <Link\n key=\"okta-domain-link\"\n href={OKTA_HELP_LINKS.domain}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </Link>\n ),\n },\n })}\n </>\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"client_id\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.okta.client_id.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"text\"\n placeholder={t('fields.okta.client_id.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n <>\n {t.trans('fields.okta.client_id.helper_text', {\n components: {\n link: (children: string) => (\n <Link\n key=\"okta-client-id-link\"\n href={OKTA_HELP_LINKS.client_id}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </Link>\n ),\n },\n })}\n </>\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"client_secret\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.okta.client_secret.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"password\"\n placeholder={t('fields.okta.client_secret.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n <>\n {t.trans('fields.okta.client_secret.helper_text', {\n components: {\n link: (children: string) => (\n <Link\n key=\"okta-client-secret-link\"\n href={OKTA_HELP_LINKS.client_secret}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </Link>\n ),\n },\n })}\n </>\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"callback_url\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.okta.callback_url.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"text\"\n placeholder={t('fields.okta.callback_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={true}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.okta.callback_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <CommonConfigureFields\n idpConfig={idpConfig}\n readOnly={readOnly}\n customMessages={customMessages}\n />\n </div>\n </Form>\n );\n },\n);\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/okta-sso-configure-form.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/ping-federate-sso-configure-form.tsx",
"content": "import {\n createProviderConfigureSchema,\n type PingFederateConfigureFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useState } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from '../../../../ui/accordion';\nimport { Checkbox } from '../../../../ui/checkbox';\nimport { FileUpload } from '../../../../ui/file-upload';\nimport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n} from '../../../../ui/form';\nimport { Link } from '../../../../ui/link';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../../../ui/select';\nimport { TextField } from '../../../../ui/text-field';\n\nimport { CommonConfigureFields } from './common-configure-fields';\n\nconst PING_FEDERATE_HELP_LINKS = {\n sign_request: 'domain/pem?cert=connection',\n} as const;\n\nconst SIGNATURE_ALGORITHMS = [\n { value: 'rsa-sha1', label: 'RSA-SHA1' },\n { value: 'rsa-sha256', label: 'RSA-SHA256' },\n] as const;\n\nconst DIGEST_ALGORITHMS = [\n { value: 'sha1', label: 'SHA1' },\n { value: 'sha256', label: 'SHA256' },\n] as const;\n\nexport interface PingFederateConfigureFormHandle {\n validate: () => Promise<boolean>;\n getData: () => PingFederateConfigureFormValues;\n isDirty: () => boolean;\n reset: (data?: PingFederateConfigureFormValues) => void;\n}\n\ninterface PingFederateConfigureFormProps extends Omit<ProviderConfigureFieldsProps, 'strategy'> {}\n\nexport const PingFederateProviderForm = React.forwardRef<\n PingFederateConfigureFormHandle,\n PingFederateConfigureFormProps\n>(function PingFederateProviderForm(\n { initialData, readOnly = false, customMessages = {}, className, onFormDirty, idpConfig },\n ref,\n) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);\n\n const pingFederateData = initialData as PingFederateConfigureFormValues | undefined;\n\n const form = useForm<PingFederateConfigureFormValues>({\n resolver: zodResolver(createProviderConfigureSchema('pingfederate')),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n pingFederateBaseUrl: pingFederateData?.pingFederateBaseUrl || '',\n signingCert: pingFederateData?.signingCert || '',\n signSAMLRequest: pingFederateData?.signSAMLRequest || false,\n signatureAlgorithm: pingFederateData?.signatureAlgorithm || 'rsa-sha256',\n digestAlgorithm: pingFederateData?.digestAlgorithm || 'sha256',\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n const signRequestEnabled = form.watch('signSAMLRequest');\n\n const handleFileUpload = async (files: File[]) => {\n setUploadedFiles(files);\n\n const file = files[0];\n if (file) {\n try {\n const content = await file.text();\n form.setValue('signingCert', content);\n } catch (error) {\n console.error('Error reading file:', error);\n }\n }\n };\n\n return (\n <Form {...form}>\n <div className={cn('space-y-6', className)}>\n <FormField\n control={form.control}\n name=\"pingFederateBaseUrl\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.ping-federate.ping_federate_baseurl.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"url\"\n placeholder={t('fields.ping-federate.ping_federate_baseurl.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n aria-invalid={Boolean(fieldState.error)}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.ping-federate.ping_federate_baseurl.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"signingCert\"\n render={() => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.ping-federate.sign_cert.label')}\n </FormLabel>\n <FormControl>\n <div className=\"space-y-3\">\n <FileUpload\n accept=\".pem\"\n onChange={handleFileUpload}\n value={uploadedFiles}\n maxFiles={1}\n disabled={readOnly}\n className=\"w-full\"\n placeholder={t('fields.ping-federate.sign_cert.placeholder')}\n />\n </div>\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.ping-federate.sign_cert.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <Accordion type=\"single\" collapsible className=\"w-full\">\n <AccordionItem value=\"advanced-settings\">\n <AccordionTrigger className=\"text-sm font-medium\">\n {t('fields.ping-federate.advanced_settings.title')}\n </AccordionTrigger>\n <AccordionContent className=\"space-y-6\">\n <FormField\n control={form.control}\n name=\"signSAMLRequest\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-2 space-y-0\">\n <FormControl>\n <Checkbox\n checked={field.value || false}\n onCheckedChange={field.onChange}\n disabled={readOnly}\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel className=\"text-sm font-medium cursor-pointer\">\n {t('fields.ping-federate.advanced_settings.sign_request.label')}\n </FormLabel>\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n <>\n {t.trans(\n 'fields.ping-federate.advanced_settings.sign_request.helper_text',\n {\n components: {\n link: (children: string) => (\n <Link\n key=\"ping-federate-sign-request-link\"\n href={PING_FEDERATE_HELP_LINKS.sign_request}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </Link>\n ),\n },\n },\n )}\n </>\n </FormDescription>\n </div>\n </FormItem>\n )}\n />\n\n {signRequestEnabled && (\n <>\n <FormField\n control={form.control}\n name=\"signatureAlgorithm\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.ping-federate.advanced_settings.sign_request_algorithm.label')}\n </FormLabel>\n <Select onValueChange={field.onChange} value={field.value || ''}>\n <FormControl>\n <SelectTrigger>\n <SelectValue\n placeholder={t(\n 'fields.ping-federate.advanced_settings.sign_request_algorithm.placeholder',\n )}\n />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {SIGNATURE_ALGORITHMS.map((algorithm) => (\n <SelectItem key={algorithm.value} value={algorithm.value}>\n {algorithm.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"digestAlgorithm\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t(\n 'fields.ping-federate.advanced_settings.sign_request_algorithm_digest.label',\n )}\n </FormLabel>\n <Select onValueChange={field.onChange} value={field.value || ''}>\n <FormControl>\n <SelectTrigger>\n <SelectValue\n placeholder={t(\n 'fields.ping-federate.advanced_settings.sign_request_algorithm_digest.placeholder',\n )}\n />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {DIGEST_ALGORITHMS.map((algorithm) => (\n <SelectItem key={algorithm.value} value={algorithm.value}>\n {algorithm.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n </>\n )}\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n\n <CommonConfigureFields\n idpConfig={idpConfig}\n readOnly={readOnly}\n customMessages={customMessages}\n />\n </div>\n </Form>\n );\n});\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/ping-federate-sso-configure-form.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/samlp-sso-configure-form.tsx",
"content": "import {\n createProviderConfigureSchema,\n type SamlpConfigureFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useState } from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from '../../../../ui/accordion';\nimport { Checkbox } from '../../../../ui/checkbox';\nimport { FileUpload } from '../../../../ui/file-upload';\nimport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n} from '../../../../ui/form';\nimport { Label } from '../../../../ui/label';\nimport { Link } from '../../../../ui/link';\nimport { RadioGroup, RadioGroupItem } from '../../../../ui/radio-group';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '../../../../ui/select';\nimport { TextField } from '../../../../ui/text-field';\n\nimport { CommonConfigureFields } from './common-configure-fields';\n\nconst SAMLP_HELP_LINKS = {\n sign_request: 'domain/pem?cert=connection',\n} as const;\n\nconst SIGNATURE_ALGORITHMS = [\n { value: 'rsa-sha1', label: 'RSA-SHA1' },\n { value: 'rsa-sha256', label: 'RSA-SHA256' },\n] as const;\n\nconst DIGEST_ALGORITHMS = [\n { value: 'sha1', label: 'SHA1' },\n { value: 'sha256', label: 'SHA256' },\n] as const;\n\nconst BINDING_METHODS = [\n { value: 'HTTP-Redirect', label: 'HTTP-Redirect' },\n { value: 'HTTP-POST', label: 'HTTP-POST' },\n] as const;\n\nexport interface SamlpConfigureFormHandle {\n validate: () => Promise<boolean>;\n getData: () => SamlpConfigureFormValues;\n isDirty: () => boolean;\n reset: (data?: SamlpConfigureFormValues) => void;\n}\n\ninterface SamlpConfigureFormProps extends Omit<ProviderConfigureFieldsProps, 'strategy'> {}\n\nexport const SamlpProviderForm = React.forwardRef<\n SamlpConfigureFormHandle,\n SamlpConfigureFormProps\n>(function SamlpProviderForm(\n { initialData, readOnly = false, customMessages = {}, className, onFormDirty, idpConfig },\n ref,\n) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const [uploadedFiles, setUploadedFiles] = useState<File[]>([]);\n\n const samlpData = initialData as SamlpConfigureFormValues | undefined;\n\n const form = useForm<SamlpConfigureFormValues>({\n resolver: zodResolver(createProviderConfigureSchema('samlp')),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n meta_data_source: samlpData?.meta_data_source || 'meta_data_url',\n metadataUrl: samlpData?.metadataUrl || '',\n single_sign_on_login_url: samlpData?.single_sign_on_login_url || '',\n cert: samlpData?.cert || '',\n signSAMLRequest: samlpData?.signSAMLRequest || false,\n signatureAlgorithm: samlpData?.signatureAlgorithm || 'rsa-sha256',\n digestAlgorithm: samlpData?.digestAlgorithm || 'sha256',\n bindingMethod: samlpData?.bindingMethod || 'HTTP-POST',\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n const typeValue = form.watch('meta_data_source');\n const showMetadataFileField = typeValue === 'meta_data_file';\n\n const signRequestEnabled = form.watch('signSAMLRequest');\n\n const handleFileUpload = async (files: File[]) => {\n setUploadedFiles(files);\n\n const file = files[0];\n if (file) {\n try {\n const content = await file.text();\n form.setValue('cert', content);\n } catch (error) {\n console.error('Error reading file:', error);\n }\n }\n };\n\n return (\n <Form {...form}>\n <div className={cn('space-y-6', className)}>\n <FormField\n control={form.control}\n name=\"meta_data_source\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.samlp.meta_data_source.label')}\n </FormLabel>\n <FormControl>\n <RadioGroup\n value={field.value}\n onValueChange={field.onChange}\n disabled={readOnly}\n className=\"flex flex-col space-y-2\"\n >\n <div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"meta_data_url\" id=\"meta_data_url\" />\n <Label htmlFor=\"meta_data_url\" className=\"text-sm font-normal cursor-pointer\">\n {t('fields.samlp.meta_data_source.options.meta_data_url.label')}\n </Label>\n </div>\n <div className=\"flex items-center space-x-2\">\n <RadioGroupItem value=\"meta_data_file\" id=\"meta_data_file\" />\n <Label htmlFor=\"meta_data_file\" className=\"text-sm font-normal cursor-pointer\">\n {t('fields.samlp.meta_data_source.options.meta_data_file.label')}\n </Label>\n </div>\n </RadioGroup>\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"metadataUrl\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.samlp.meta_data_url.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"url\"\n placeholder={t('fields.samlp.meta_data_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n aria-required={true}\n aria-invalid={Boolean(fieldState.error)}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.samlp.meta_data_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n {showMetadataFileField && (\n <>\n <FormField\n control={form.control}\n name=\"single_sign_on_login_url\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.samlp.single_sign_on_login_url.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"url\"\n placeholder={t('fields.samlp.single_sign_on_login_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n aria-required={true}\n aria-invalid={Boolean(fieldState.error)}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.samlp.single_sign_on_login_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n <FormField\n control={form.control}\n name=\"cert\"\n render={() => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.samlp.cert.label')}\n </FormLabel>\n <FormControl>\n <div className=\"space-y-3\">\n <FileUpload\n accept=\".pem\"\n onChange={handleFileUpload}\n value={uploadedFiles}\n maxFiles={1}\n disabled={readOnly}\n className=\"w-full\"\n placeholder={t('fields.samlp.cert.placeholder')}\n />\n </div>\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.samlp.cert.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n </>\n )}\n\n <Accordion type=\"single\" collapsible className=\"w-full\">\n <AccordionItem value=\"advanced-settings\">\n <AccordionTrigger className=\"text-sm font-medium\">\n {t('fields.samlp.advanced_settings.title')}\n </AccordionTrigger>\n <AccordionContent className=\"space-y-6\">\n <FormField\n control={form.control}\n name=\"signSAMLRequest\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-2 space-y-0\">\n <FormControl>\n <Checkbox\n checked={field.value || false}\n onCheckedChange={field.onChange}\n disabled={readOnly}\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel className=\"text-sm font-medium cursor-pointer\">\n {t('fields.samlp.advanced_settings.sign_request.label')}\n </FormLabel>\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n <>\n {t.trans(\n typeValue === 'meta_data_url'\n ? 'fields.samlp.advanced_settings.sign_request.helper_text_metadata_url'\n : 'fields.samlp.advanced_settings.sign_request.helper_text_metadata_file',\n {\n components: {\n link: (children: string) => (\n <Link\n key=\"samlp-sign-request-link\"\n href={SAMLP_HELP_LINKS.sign_request}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {children}\n </Link>\n ),\n },\n },\n )}\n </>\n </FormDescription>\n </div>\n </FormItem>\n )}\n />\n\n {signRequestEnabled && (\n <>\n <FormField\n control={form.control}\n name=\"signatureAlgorithm\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.samlp.advanced_settings.sign_request_algorithm.label')}\n </FormLabel>\n <Select onValueChange={field.onChange} value={field.value || ''}>\n <FormControl>\n <SelectTrigger>\n <SelectValue\n placeholder={t(\n 'fields.samlp.advanced_settings.sign_request_algorithm.placeholder',\n )}\n />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {SIGNATURE_ALGORITHMS.map((algorithm) => (\n <SelectItem key={algorithm.value} value={algorithm.value}>\n {algorithm.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"digestAlgorithm\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.samlp.advanced_settings.sign_request_algorithm_digest.label')}\n </FormLabel>\n <Select onValueChange={field.onChange} value={field.value || ''}>\n <FormControl>\n <SelectTrigger>\n <SelectValue\n placeholder={t(\n 'fields.samlp.advanced_settings.sign_request_algorithm_digest.placeholder',\n )}\n />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {DIGEST_ALGORITHMS.map((algorithm) => (\n <SelectItem key={algorithm.value} value={algorithm.value}>\n {algorithm.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n </>\n )}\n <FormField\n control={form.control}\n name=\"bindingMethod\"\n render={({ field }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.samlp.advanced_settings.request_protocol_binding.label')}\n </FormLabel>\n <Select onValueChange={field.onChange} value={field.value || ''}>\n <FormControl>\n <SelectTrigger>\n <SelectValue\n placeholder={t(\n 'fields.samlp.advanced_settings.request_protocol_binding.placeholder',\n )}\n />\n </SelectTrigger>\n </FormControl>\n <SelectContent>\n {BINDING_METHODS.map((method) => (\n <SelectItem key={method.value} value={method.value}>\n {method.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n </AccordionContent>\n </AccordionItem>\n </Accordion>\n\n <CommonConfigureFields\n idpConfig={idpConfig}\n readOnly={readOnly}\n customMessages={customMessages}\n />\n </div>\n </Form>\n );\n});\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/samlp-sso-configure-form.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/waad-sso-configure-form.tsx",
"content": "import {\n createProviderConfigureSchema,\n type WaadConfigureFormValues,\n} from '@auth0/universal-components-core';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport * as React from 'react';\nimport { useForm } from 'react-hook-form';\n\nimport { useProviderFormMode } from '../../../../../hooks/my-organization/idp-management/use-provider-form-mode';\nimport { useCoreClient } from '../../../../../hooks/use-core-client';\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport { cn } from '../../../../../lib/theme-utils';\nimport type { ProviderConfigureFieldsProps } from '../../../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\nimport { CopyableTextField } from '../../../../ui/copyable-text-field';\nimport {\n Form,\n FormField,\n FormItem,\n FormLabel,\n FormControl,\n FormMessage,\n FormDescription,\n} from '../../../../ui/form';\nimport { TextField } from '../../../../ui/text-field';\n\nimport { CommonConfigureFields } from './common-configure-fields';\n\nexport interface WaadConfigureFormHandle {\n validate: () => Promise<boolean>;\n getData: () => WaadConfigureFormValues;\n isDirty: () => boolean;\n reset: (data?: WaadConfigureFormValues) => void;\n}\n\ninterface WaadConfigureFormProps extends Omit<ProviderConfigureFieldsProps, 'strategy'> {}\n\nexport const WaadProviderForm = React.forwardRef<WaadConfigureFormHandle, WaadConfigureFormProps>(\n function WaadProviderForm(\n {\n initialData,\n readOnly = false,\n customMessages = {},\n className,\n onFormDirty,\n idpConfig,\n mode = 'create',\n },\n ref,\n ) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const { coreClient } = useCoreClient();\n const { showCopyButtons } = useProviderFormMode(mode);\n\n const callbackUrl = React.useMemo(() => {\n const domain = coreClient?.auth?.domain || 'YOUR_DOMAIN';\n return `https://${domain}/login/callback`;\n }, [coreClient?.auth?.domain]);\n\n const waadData = initialData as WaadConfigureFormValues | undefined;\n\n const form = useForm<WaadConfigureFormValues>({\n resolver: zodResolver(createProviderConfigureSchema('waad')),\n mode: 'onSubmit',\n reValidateMode: 'onChange',\n defaultValues: {\n tenant_domain: waadData?.tenant_domain || '',\n client_id: waadData?.client_id || '',\n client_secret: waadData?.client_secret || '',\n callback_url: waadData?.callback_url || callbackUrl,\n },\n });\n\n const { isDirty } = form.formState;\n\n React.useEffect(() => {\n onFormDirty?.(isDirty);\n }, [isDirty, onFormDirty]);\n\n React.useImperativeHandle(ref, () => ({\n validate: async () => {\n return await form.trigger();\n },\n getData: () => form.getValues(),\n isDirty: () => form.formState.isDirty,\n reset: (data) => {\n if (data) {\n form.reset(data);\n } else {\n form.reset();\n }\n },\n }));\n\n return (\n <Form {...form}>\n <div className={cn('space-y-6', className)}>\n <FormField\n control={form.control}\n name=\"tenant_domain\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.waad.tenant_domain.label')}\n </FormLabel>\n <FormControl>\n <TextField\n type=\"text\"\n placeholder={t('fields.waad.tenant_domain.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"client_id\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.waad.client_id.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"text\"\n placeholder={t('fields.waad.client_id.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.waad.client_id.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"client_secret\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.waad.client_secret.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"password\"\n placeholder={t('fields.waad.client_secret.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={readOnly}\n showCopyButton={showCopyButtons}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.waad.client_secret.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <FormField\n control={form.control}\n name=\"callback_url\"\n render={({ field, fieldState }) => (\n <FormItem>\n <FormLabel className=\"text-sm font-medium text-(length:--font-size-label)\">\n {t('fields.waad.callback_url.label')}\n </FormLabel>\n <FormControl>\n <CopyableTextField\n type=\"text\"\n placeholder={t('fields.waad.callback_url.placeholder')}\n error={Boolean(fieldState.error)}\n readOnly={true}\n {...field}\n />\n </FormControl>\n <FormMessage\n role=\"alert\"\n className=\"text-sm text-left text-(length:--font-size-paragraph)\"\n />\n <FormDescription className=\"text-sm text-(length:--font-size-paragraph) font-normal text-left\">\n {t('fields.waad.callback_url.helper_text')}\n </FormDescription>\n </FormItem>\n )}\n />\n\n <CommonConfigureFields\n idpConfig={idpConfig}\n readOnly={readOnly}\n customMessages={customMessages}\n />\n </div>\n </Form>\n );\n },\n);\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/waad-sso-configure-form.tsx"
},
{
"path": "src/components/ui/accordion.tsx",
"content": "'use client';\n\nimport * as AccordionPrimitive from '@radix-ui/react-accordion';\nimport { ChevronDown } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nfunction Accordion({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Root>) {\n return (\n <AccordionPrimitive.Root\n data-slot=\"accordion\"\n className={cn('w-full space-y-2 bg-card', className)}\n {...props}\n />\n );\n}\n\nfunction AccordionItem({\n className,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Item>) {\n return (\n <AccordionPrimitive.Item\n data-slot=\"accordion-item\"\n className={cn(\n 'text-card-foreground shadow-bevel-2xl flex flex-col rounded-2xl transition-all duration-150 ease-in-out',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction AccordionTrigger({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {\n return (\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger\n data-slot=\"accordion-trigger\"\n className={cn(\n 'group text-foreground focus-visible:ring-ring flex w-full items-center justify-between p-6 text-sm font-medium transition-all duration-150 ease-in-out focus-visible:ring-2 focus-visible:outline-hidden disabled:cursor-not-allowed [&[data-state=open]>svg]:rotate-180',\n className,\n )}\n {...props}\n >\n {children}\n <ChevronDown className=\"text-muted-foreground size-4 shrink-0 transition-transform duration-150\" />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n );\n}\n\nfunction AccordionContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof AccordionPrimitive.Content>) {\n return (\n <AccordionPrimitive.Content\n data-slot=\"accordion-content\"\n className=\"data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm\"\n {...props}\n >\n <div\n className={cn(\n 'text-muted-foreground border-border animate-in fade-in-50 px-6 pb-6 min-h-10 text-sm transition-all duration-150 ease-in-out',\n className,\n )}\n >\n {children}\n </div>\n </AccordionPrimitive.Content>\n );\n}\n\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/accordion.tsx"
},
{
"path": "src/components/ui/button.tsx",
"content": "'use client';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nconst buttonVariants = cva(\n \"focus-visible:ring-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive theme-default:active:scale-[0.99] relative box-border inline-flex shrink-0 items-center justify-center gap-2 overflow-hidden text-sm font-medium whitespace-nowrap transition-all duration-150 ease-in-out outline-none focus-visible:ring-4 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n primary:\n \"shadow-button-resting hover:shadow-button-hover hover:border-primary/50 border-primary bg-primary text-primary-foreground hover:bg-primary/90 theme-default:before:from-primary-foreground/0 theme-default:before:to-primary-foreground/15 theme-default:before:absolute theme-default:before:top-0 theme-default:before:left-0 theme-default:before:block theme-default:before:h-full theme-default:before:w-full theme-default:before:bg-gradient-to-t theme-default:before:content-[''] border\",\n outline:\n \"dark:bg-muted/50 hover:text-accent-foreground shadow-button-outlined-resting hover:shadow-button-outlined-hover hover:border-accent bg-background hover:bg-muted text-primary border-primary/35 theme-default:before:from-primary/5 theme-default:before:to-primary/0 theme-default:before:absolute theme-default:before:top-0 theme-default:before:left-0 theme-default:before:block theme-default:before:h-full theme-default:before:w-full theme-default:before:bg-gradient-to-t theme-default:before:content-[''] border\",\n ghost: 'hover:bg-muted text-primary bg-transparent',\n destructive:\n \"bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-button-destructive-resting hover:shadow-button-destructive-hover border-destructive-border/25 hover:border-destructive-border/50 theme-default:before:to-primary-foreground/50 theme-default:before:absolute theme-default:before:top-0 theme-default:before:left-0 theme-default:before:block theme-default:before:h-full theme-default:before:w-full theme-default:before:bg-gradient-to-t theme-default:before:content-[''] theme-default:border\",\n link: 'text-foreground underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 rounded-2xl px-4 py-2.5 has-[>svg]:px-3',\n xs: 'h-7 rounded-md px-2 py-1.5 text-xs has-[>svg]:px-2',\n sm: 'h-8 gap-1.5 rounded-xl px-3 py-2 text-xs has-[>svg]:px-2.5',\n lg: 'h-12 rounded-3xl px-6 py-3 text-base has-[>svg]:px-4',\n icon: 'size-7 rounded-xl',\n },\n },\n defaultVariants: {\n variant: 'primary',\n size: 'default',\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n as?: boolean;\n}\n\nfunction Button({\n className,\n variant,\n size,\n as,\n ...props\n}: React.ComponentProps<'button'> & ButtonProps) {\n const Comp = as ? Slot : 'button';\n\n return <Comp className={cn(buttonVariants({ variant, size }), className)} {...props} />;\n}\n\nexport { Button, buttonVariants };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/button.tsx"
},
{
"path": "src/components/ui/card.tsx",
"content": "import * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nfunction Card({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card\"\n className={cn(\n 'bg-card text-card-foreground shadow-bevel-2xl flex flex-col gap-6 rounded-4xl py-6',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n '@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6',\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn('leading-none font-semibold', className)}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n );\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn('col-start-2 row-span-2 row-start-1 self-start justify-self-end', className)}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-content\" className={cn('px-6', className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn('flex items-center px-6 [.border-t]:pt-6', className)}\n {...props}\n />\n );\n}\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/card.tsx"
},
{
"path": "src/components/ui/checkbox.tsx",
"content": "import * as CheckboxPrimitive from '@radix-ui/react-checkbox';\nimport { CheckIcon, MinusIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n 'group shadow-checkbox-resting peer hover:shadow-checkbox-hover focus-visible:ring-ring hover:border-primary/50 border-border data-[state=checked]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive relative flex size-6 shrink-0 appearance-none items-center justify-center rounded-lg border transition-[colors,shadow] duration-150 ease-in-out outline-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"group-data-[state=checked]:animate-in group-data-[state=unchecked]:animate-out group-data-[state=unchecked]:fade-out-0 group-data-[state=checked]:fade-in-0 group-data-[state=unchecked]:slide-out-to-bottom-5 group-data-[state=unchecked]:zoom-out-75 group-data-[state=checked]:zoom-in-75 group-data-[state=checked]:slide-in-from-bottom-5 text-primary-foreground stroke-primary-foreground duration-150 ease-in-out group-data-[state=checked]:block\"\n >\n {props.checked === 'indeterminate' ? (\n <MinusIcon className=\"size-3 stroke-[4px]\" absoluteStrokeWidth />\n ) : (\n <CheckIcon className=\"size-3 stroke-[4px]\" absoluteStrokeWidth />\n )}\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\nexport { Checkbox };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/checkbox.tsx"
},
{
"path": "src/components/ui/copyable-text-field.tsx",
"content": "import { Copy } from 'lucide-react';\nimport * as React from 'react';\n\nimport { useTranslator } from '../../hooks/use-translator';\nimport { cn } from '../../lib/theme-utils';\n\nimport { Button } from './button';\nimport { TextField, type TextFieldProps } from './text-field';\nimport { Tooltip, TooltipTrigger, TooltipContent } from './tooltip';\n\nexport interface CopyableTextFieldProps extends TextFieldProps {\n onCopy?: () => void;\n copyButtonClassName?: string;\n tooltipSide?: 'top' | 'bottom' | 'left' | 'right';\n tooltipAlign?: 'start' | 'center' | 'end';\n showCopyButton?: boolean;\n}\n\nconst CopyableTextField = React.forwardRef<HTMLInputElement, CopyableTextFieldProps>(\n (\n {\n onCopy,\n copyButtonClassName,\n tooltipSide = 'top',\n tooltipAlign = 'end',\n readOnly = true,\n endAdornment,\n showCopyButton = true,\n ...props\n },\n ref,\n ) => {\n const { t } = useTranslator('common');\n const [tooltipText, setTooltipText] = React.useState(t('copy'));\n const [tooltipOpen, setTooltipOpen] = React.useState(false);\n\n const handleCopy = async () => {\n if (props.value) {\n await navigator.clipboard.writeText(String(props.value));\n setTooltipText(t('copied'));\n setTooltipOpen(true);\n setTimeout(() => {\n setTooltipText(t('copy'));\n setTooltipOpen(false);\n }, 1000);\n onCopy?.();\n }\n };\n\n const copyButton = (\n <Tooltip open={tooltipOpen} onOpenChange={setTooltipOpen}>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className={cn('h-8 w-8', copyButtonClassName)}\n onClick={handleCopy}\n aria-label={t('copy')}\n >\n <Copy className=\"h-4 w-4\" aria-hidden=\"true\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side={tooltipSide} align={tooltipAlign} sideOffset={5} className=\"z-[1000]\">\n {tooltipText}\n </TooltipContent>\n </Tooltip>\n );\n\n return (\n <TextField\n ref={ref}\n readOnly={readOnly}\n {...props}\n endAdornment={\n showCopyButton ? (\n endAdornment ? (\n <div className=\"flex items-center gap-1\">\n {endAdornment}\n {copyButton}\n </div>\n ) : (\n copyButton\n )\n ) : (\n endAdornment\n )\n }\n />\n );\n },\n);\n\nCopyableTextField.displayName = 'CopyableTextField';\n\nexport { CopyableTextField };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/copyable-text-field.tsx"
},
{
"path": "src/components/ui/file-upload.tsx",
"content": "import { Upload, X } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nexport interface FileUploadProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'value' | 'onChange'> {\n value?: File[];\n onChange?: (files: File[]) => void;\n onRemove?: (file: File) => void;\n maxSize?: number;\n accept?: string;\n maxFiles?: number;\n preview?: boolean;\n className?: string;\n}\n\nexport function FileUpload({\n value = [],\n onChange,\n onRemove,\n maxSize,\n accept,\n maxFiles = 1,\n preview = true,\n className,\n disabled,\n ...props\n}: FileUploadProps) {\n const inputRef = React.useRef<HTMLInputElement>(null);\n const [dragActive, setDragActive] = React.useState(false);\n\n const handleDrag = React.useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n if (e.type === 'dragenter' || e.type === 'dragover') {\n setDragActive(true);\n } else if (e.type === 'dragleave') {\n setDragActive(false);\n }\n }, []);\n\n const handleDrop = React.useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setDragActive(false);\n\n const files = Array.from(e.dataTransfer.files);\n handleFiles(files);\n }, []);\n\n const handleChange = React.useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const files = Array.from(e.target.files || []);\n handleFiles(files);\n }, []);\n\n const handleFiles = React.useCallback(\n (files: File[]) => {\n if (disabled) return;\n const validFiles = files.filter((file) => {\n if (maxSize && file.size > maxSize) return false;\n if (\n accept &&\n !accept.split(',').some((type) => {\n const fileType = type.trim().toLowerCase();\n const fileName = file.name.toLowerCase();\n const fileMimeType = file.type.toLowerCase();\n if (fileType.startsWith('.')) {\n return fileName.endsWith(fileType);\n }\n\n if (fileType === fileMimeType) {\n return true;\n }\n\n if (fileType.endsWith('/*')) {\n const baseType = fileType.slice(0, -2);\n return fileMimeType.startsWith(`${baseType}/`);\n }\n\n return false;\n })\n )\n return false;\n return true;\n });\n\n if (maxFiles === 1) {\n onChange?.(validFiles.slice(0, 1));\n } else {\n onChange?.([...value, ...validFiles].slice(0, maxFiles));\n }\n\n if (inputRef.current) inputRef.current.value = '';\n },\n [disabled, maxSize, accept, maxFiles, onChange, value],\n );\n\n const removeFile = React.useCallback(\n (file: File) => {\n onRemove?.(file);\n onChange?.(value.filter((f) => f !== file));\n },\n [onChange, onRemove, value],\n );\n\n return (\n <div className={cn('space-y-4', className)}>\n <div\n onDragEnter={handleDrag}\n onDragLeave={handleDrag}\n onDragOver={handleDrag}\n onDrop={handleDrop}\n className={cn(\n 'border-muted-foreground/25 relative flex min-h-[150px] cursor-pointer items-center justify-center rounded-lg border-2 border-dashed p-4 text-center transition-colors',\n dragActive && 'border-primary',\n disabled && 'cursor-not-allowed opacity-60',\n className,\n )}\n >\n <input\n ref={inputRef}\n type=\"file\"\n multiple={maxFiles !== 1}\n accept={accept}\n onChange={handleChange}\n disabled={disabled}\n className=\"absolute inset-0 cursor-pointer opacity-0 disabled:cursor-not-allowed\"\n {...props}\n />\n <div className=\"flex flex-col items-center gap-2\">\n <Upload className=\"text-muted-foreground h-8 w-8\" />\n <p className=\"text-muted-foreground text-sm\">\n Drag & drop files here, or click to select files\n </p>\n {accept && <p className=\"text-muted-foreground text-xs\">Allowed files: {accept}</p>}\n {maxSize && (\n <p className=\"text-muted-foreground text-xs\">\n Max size: {(maxSize / 1024 / 1024).toFixed(2)}MB\n </p>\n )}\n </div>\n </div>\n\n {preview && value.length > 0 && (\n <div className=\"grid gap-4\">\n {value.map((file, i) => (\n <div key={i} className=\"flex items-center gap-2 rounded-md border p-2\">\n <div className=\"flex-1 truncate\">\n <p className=\"text-sm font-medium\">{file.name}</p>\n <p className=\"text-muted-foreground text-xs\">{(file.size / 1024).toFixed(2)}KB</p>\n </div>\n <button\n type=\"button\"\n onClick={() => removeFile(file)}\n className=\"hover:bg-muted shrink-0 rounded-md p-1 transition-colors\"\n disabled={disabled}\n >\n <X className=\"size-4\" />\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/file-upload.tsx"
},
{
"path": "src/components/ui/form.tsx",
"content": "'use client';\n\nimport type * as LabelPrimitive from '@radix-ui/react-label';\nimport { Slot } from '@radix-ui/react-slot';\nimport * as React from 'react';\nimport {\n Controller,\n FormProvider,\n useFormContext,\n useFormState,\n type ControllerProps,\n type FieldPath,\n type FieldValues,\n} from 'react-hook-form';\n\nimport { cn } from '../../lib/theme-utils';\n\nimport { Label } from './label';\n\nconst Form: typeof FormProvider = FormProvider;\n\ntype FormFieldContextValue<\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n> = {\n name: TName;\n};\n\nconst FormFieldContext = React.createContext<FormFieldContextValue>({} as FormFieldContextValue);\n\nconst FormField = <\n TFieldValues extends FieldValues = FieldValues,\n TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,\n>({\n ...props\n}: ControllerProps<TFieldValues, TName>) => {\n return (\n <FormFieldContext.Provider value={{ name: props.name }}>\n <Controller\n {...props}\n render={({ field, fieldState, formState }) => {\n const { onChange, onBlur, ...rest } = field;\n return props.render({\n field: {\n ...rest,\n onChange: (...args: unknown[]) => {\n onChange(...(args as Parameters<typeof onChange>));\n },\n onBlur: (...args: unknown[]) => {\n onBlur(...(args as Parameters<typeof onBlur>));\n },\n },\n fieldState,\n formState,\n });\n }}\n />\n </FormFieldContext.Provider>\n );\n};\n\nconst useFormField = () => {\n const fieldContext = React.useContext(FormFieldContext);\n const itemContext = React.useContext(FormItemContext);\n const { getFieldState } = useFormContext();\n const formState = useFormState({ name: fieldContext.name });\n const fieldState = getFieldState(fieldContext.name, formState);\n\n if (!fieldContext) {\n throw new Error('useFormField should be used within <FormField>');\n }\n\n const { id } = itemContext;\n\n return {\n id,\n name: fieldContext.name,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n ...fieldState,\n };\n};\n\ntype FormItemContextValue = {\n id: string;\n};\n\nconst FormItemContext = React.createContext<FormItemContextValue>({} as FormItemContextValue);\n\nfunction FormItem({ className, ...props }: React.ComponentProps<'div'>) {\n const id = React.useId();\n\n return (\n <FormItemContext.Provider value={{ id }}>\n <div data-slot=\"form-item\" className={cn('grid gap-2', className)} {...props} />\n </FormItemContext.Provider>\n );\n}\n\nfunction FormLabel({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {\n const { error, formItemId } = useFormField();\n\n return (\n <Label\n data-slot=\"form-label\"\n data-error={!!error}\n className={cn('data-[error=true]:text-destructive-foreground', className)}\n htmlFor={formItemId}\n {...props}\n />\n );\n}\n\nfunction FormControl({ ...props }: React.ComponentProps<typeof Slot>) {\n const { error, formItemId, formDescriptionId, formMessageId } = useFormField();\n\n return (\n <Slot\n data-slot=\"form-control\"\n id={formItemId}\n aria-describedby={!error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`}\n aria-invalid={!!error}\n {...props}\n />\n );\n}\n\nfunction FormDescription({ className, ...props }: React.ComponentProps<'p'>) {\n const { formDescriptionId } = useFormField();\n\n return (\n <p\n data-slot=\"form-description\"\n id={formDescriptionId}\n className={cn('text-muted-foreground text-sm', className)}\n {...props}\n />\n );\n}\n\nfunction FormMessage({ className, ...props }: React.ComponentProps<'p'>) {\n const { error, formMessageId } = useFormField();\n const body = error ? String(error?.message ?? '') : props.children;\n\n if (!body) {\n return null;\n }\n\n return (\n <p\n data-slot=\"form-message\"\n id={formMessageId}\n className={cn('text-destructive-foreground text-sm', className)}\n {...props}\n >\n {body}\n </p>\n );\n}\n\nexport {\n useFormField,\n Form,\n FormItem,\n FormLabel,\n FormControl,\n FormDescription,\n FormMessage,\n FormField,\n};\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/form.tsx"
},
{
"path": "src/components/ui/form-actions.tsx",
"content": "import type { ActionButton } from '@auth0/universal-components-core';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nimport { Button } from './button';\nimport { Spinner } from './spinner';\n\nexport interface FormActionsProps<T = void> {\n hasUnsavedChanges?: boolean;\n isLoading?: boolean;\n nextAction?: Partial<ActionButton<T>>;\n previousAction?: Partial<ActionButton<T>>;\n showPrevious?: boolean;\n showNext?: boolean;\n showUnsavedChanges?: boolean;\n align?: 'left' | 'right';\n className?: string;\n unsavedChangesText?: string;\n}\n\nconst DEFAULT_NEXT_ACTION: ActionButton = {\n type: 'submit',\n label: 'Save',\n variant: 'primary',\n onClick: () => {},\n};\n\nconst DEFAULT_PREVIOUS_ACTION: ActionButton = {\n label: 'Cancel',\n variant: 'outline',\n onClick: () => {},\n};\n\nexport const FormActions: React.FC<FormActionsProps> = ({\n hasUnsavedChanges = false,\n isLoading = false,\n nextAction,\n previousAction,\n className,\n showPrevious = true,\n showNext = true,\n showUnsavedChanges = true,\n align = 'right',\n unsavedChangesText = 'Unsaved changes',\n}) => {\n const nextButtonProps = React.useMemo(\n () => ({ ...DEFAULT_NEXT_ACTION, ...nextAction }),\n [nextAction],\n );\n\n const previousButtonProps = React.useMemo(\n () => ({ ...DEFAULT_PREVIOUS_ACTION, ...previousAction }),\n [previousAction],\n );\n\n const handleNextClick = React.useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n nextButtonProps.onClick(e.nativeEvent);\n },\n [nextButtonProps.onClick],\n );\n\n const handlePreviousClick = React.useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n previousButtonProps.onClick(e.nativeEvent);\n },\n [previousButtonProps.onClick],\n );\n\n const showUnsavedIndicator = showUnsavedChanges && hasUnsavedChanges;\n\n return (\n <div\n className={cn(\n 'flex flex-row items-center gap-2 p-2',\n align === 'right' ? 'justify-end' : 'justify-start',\n className,\n )}\n >\n {showUnsavedIndicator && (\n <div className=\"flex items-center gap-2\">\n <div\n className=\"w-2 h-2 rounded-full bg-orange-500 transition-colors\"\n aria-hidden=\"true\"\n />\n <span className=\"text-sm text-muted-foreground\">{unsavedChangesText}</span>\n </div>\n )}\n\n {showPrevious && (\n <Button\n type=\"button\"\n variant={previousButtonProps.variant}\n size={previousButtonProps.size}\n onClick={handlePreviousClick}\n disabled={previousButtonProps.disabled || isLoading}\n className=\"FormActions-previous\"\n >\n {previousButtonProps.label}\n </Button>\n )}\n\n {showNext && (\n <Button\n type={nextButtonProps.type}\n variant={nextButtonProps.variant}\n size={nextButtonProps.size}\n disabled={nextButtonProps.disabled || isLoading}\n className=\"FormActions-next\"\n {...(nextButtonProps.type !== 'submit' && { onClick: handleNextClick })}\n >\n {isLoading ? (\n <Spinner\n colorScheme={nextButtonProps.variant === 'destructive' ? 'primary' : 'foreground'}\n size=\"sm\"\n aria-hidden=\"true\"\n />\n ) : (\n <>\n {nextButtonProps.icon && (\n <span className=\"mr-2\" aria-hidden=\"true\">\n {nextButtonProps.icon as React.ReactNode}\n </span>\n )}\n {nextButtonProps.label}\n </>\n )}\n </Button>\n )}\n </div>\n );\n};\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/form-actions.tsx"
},
{
"path": "src/components/ui/header.tsx",
"content": "import type { ActionButton as CoreActionButton } from '@auth0/universal-components-core';\nimport type { LucideIcon } from 'lucide-react';\nimport { ArrowLeft } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nimport { Button } from './button';\nimport { Spinner } from './spinner';\nimport { Switch } from './switch';\nimport { Tooltip, TooltipTrigger, TooltipContent } from './tooltip';\n\nexport interface TooltipProps {\n content: React.ReactNode | string;\n}\n\nexport interface WithTooltipProps {\n trigger: React.ReactNode | string;\n tooltip: TooltipProps;\n}\n\nexport interface BaseActionProps extends Omit<CoreActionButton, 'icon' | 'onClick'> {\n icon?: LucideIcon;\n className?: string;\n hidden?: boolean;\n tooltip?: TooltipProps;\n}\n\nexport interface ButtonActionProps extends BaseActionProps {\n type: 'button';\n onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nexport interface SwitchActionProps extends Omit<BaseActionProps, 'type' | 'label'> {\n type: 'switch';\n checked?: boolean;\n onCheckedChange: (checked: boolean) => void;\n 'aria-label'?: string;\n}\n\nexport type ActionProps = ButtonActionProps | SwitchActionProps;\n\nexport interface HeaderProps {\n title?: string;\n description?: string;\n backButton?: {\n text?: string;\n icon?: LucideIcon;\n onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;\n };\n actions?: ActionProps[];\n isLoading?: boolean;\n className?: string;\n}\n\nconst WithTooltip: React.FC<WithTooltipProps> = ({ trigger, tooltip }) => (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <div>{trigger}</div>\n </TooltipTrigger>\n <TooltipContent>{tooltip.content}</TooltipContent>\n </Tooltip>\n </>\n);\n\nconst ButtonAction: React.FC<ButtonActionProps> = ({\n icon: Icon,\n className,\n label,\n onClick,\n disabled,\n variant,\n size,\n}) => (\n <Button\n onClick={onClick}\n disabled={disabled}\n variant={variant}\n size={size}\n className={cn('flex items-center gap-2 w-full sm:w-auto sm:min-w-fit', className)}\n aria-label={label}\n >\n {Icon && <Icon className=\"h-4 w-4 flex-shrink-0\" aria-hidden=\"true\" />}\n <span className=\"truncate\">{label}</span>\n </Button>\n);\n\nconst SwitchAction: React.FC<SwitchActionProps> = ({\n className,\n 'aria-label': ariaLabel,\n checked,\n onCheckedChange,\n disabled,\n}) => (\n <div className={cn('flex items-center gap-2', className)}>\n <Switch\n checked={checked}\n onCheckedChange={onCheckedChange}\n disabled={disabled}\n aria-label={ariaLabel}\n />\n </div>\n);\n\nexport const Header = React.forwardRef<\n HTMLDivElement,\n HeaderProps & React.HTMLAttributes<HTMLDivElement>\n>(({ title, description, backButton, actions, isLoading, className, ...props }, ref) => {\n const BackIcon = backButton?.icon || ArrowLeft;\n\n const renderAction = (action: ActionProps, index: number) => {\n const key = `action-${index}`;\n if (isLoading) {\n return <Spinner className=\"w-4 h-4\" />;\n }\n if (action.hidden) {\n return null;\n }\n const actionElement =\n action.type === 'switch' ? (\n <SwitchAction key={key} {...action} />\n ) : (\n <ButtonAction key={key} {...action} />\n );\n if (action.tooltip) {\n return (\n <WithTooltip key={`tooltip-${key}`} trigger={actionElement} tooltip={action.tooltip} />\n );\n }\n return actionElement;\n };\n\n return (\n <div\n ref={ref}\n className={cn('w-full mb-8', className)}\n role=\"banner\"\n aria-label={title ? `${title} header` : 'Header'}\n {...props}\n >\n {backButton && (\n <Button\n variant=\"link\"\n onClick={backButton.onClick}\n size=\"default\"\n className=\"flex items-center text-sm mb-3\"\n aria-label={backButton.text || 'Go back'}\n >\n <BackIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n {backButton.text && <span>{backButton.text}</span>}\n </Button>\n )}\n\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex flex-col min-w-0 flex-1\">\n {title && (\n <h1\n className={cn(\n 'text-xl sm:text-2xl text-primary md:text-4xl font-bold leading-tight break-words text-left text-(length:--font-size-page-header) mb-0',\n )}\n >\n {title}\n </h1>\n )}\n {description && (\n <p\n className={cn(\n 'text-base text-muted-foreground leading-relaxed break-words text-left text-(length:--font-size-page-description) mt-2',\n )}\n >\n {description}\n </p>\n )}\n </div>\n\n {actions && actions.length > 0 && (\n <div className=\"flex-shrink-0 flex items-start gap-2 mt-1\">\n {actions.map(renderAction)}\n </div>\n )}\n </div>\n </div>\n );\n});\n\nHeader.displayName = 'Header';\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/header.tsx"
},
{
"path": "src/components/ui/label.tsx",
"content": "import * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nexport function Label({ children, className, ...props }: React.ComponentPropsWithoutRef<'label'>) {\n return (\n <label\n className={cn(\n 'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',\n className,\n )}\n {...props}\n >\n {children}\n </label>\n );\n}\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/label.tsx"
},
{
"path": "src/components/ui/link.tsx",
"content": "import { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nconst linkVariants = cva(\n 'focus-within:ring-ring inline-flex items-center gap-2 rounded-md py-0.5 underline-offset-4 transition-colors focus:ring-3 focus-visible:outline-hidden',\n {\n variants: {\n variant: {\n destructive: 'text-destructive hover:text-destructive/90',\n muted: 'text-muted hover:text-muted/80',\n primary: 'text-primary hover:text-primary/90',\n },\n underline: {\n none: 'no-underline',\n hover: 'no-underline hover:underline',\n always: 'underline',\n },\n },\n defaultVariants: {\n variant: 'primary',\n underline: 'always',\n },\n },\n);\n\nexport interface LinkProps\n extends React.AnchorHTMLAttributes<HTMLAnchorElement>,\n VariantProps<typeof linkVariants> {\n /**\n * Optional ref for the link element.\n */\n ref?: React.Ref<HTMLAnchorElement>;\n}\n\nfunction Link({ ref, className, children, variant, underline, ...props }: LinkProps) {\n return (\n <a ref={ref} className={cn(linkVariants({ variant, underline }), className)} {...props}>\n {children}\n </a>\n );\n}\n\nexport { Link };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/link.tsx"
},
{
"path": "src/components/ui/radio-group.tsx",
"content": "import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nfunction RadioGroup({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {\n return (\n <RadioGroupPrimitive.RadioGroup\n data-slot=\"radio-group\"\n className={cn('space-y-2', className)}\n {...props}\n />\n );\n}\n\nfunction RadioGroupItem({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {\n return (\n <RadioGroupPrimitive.Item\n data-slot=\"radio-group-item\"\n className={cn(\n 'shadow-checkbox-resting peer border-border hover:shadow-checkbox-hover data-[state=checked]:hover:border-primary data-[state=checked]:border-primary hover:border-accent focus-visible:ring-ring data-[disabled]:border-border/50 data-[disabled]:bg-muted/50 data-[disabled]:data-[state=checked]:border-border/50 size-5 appearance-none rounded-full border transition-all duration-150 ease-in-out focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed data-[state=checked]:border-7',\n className,\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator\n data-slot=\"radio-group-indicator\"\n className=\"fill-primary-foreground top-1/2 left-1/2 hidden size-2 -translate-x-1/2 -translate-y-1/2 data-[checked]:absolute\"\n />\n </RadioGroupPrimitive.Item>\n );\n}\n\nexport { RadioGroup, RadioGroupItem };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/radio-group.tsx"
},
{
"path": "src/components/ui/section.tsx",
"content": "import type { ActionButton as CoreActionButton } from '@auth0/universal-components-core';\nimport type { LucideIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nimport { Button } from './button';\nimport { Toggle } from './toggle';\n\nexport interface BaseActionProps extends Omit<CoreActionButton, 'icon' | 'onClick'> {\n icon?: LucideIcon;\n className?: string;\n}\n\nexport interface ButtonActionProps extends BaseActionProps {\n type: 'button';\n onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;\n}\n\nexport interface ToggleActionProps extends Omit<BaseActionProps, 'type'> {\n type: 'toggle';\n pressed?: boolean;\n onPressedChange: (pressed: boolean) => void;\n 'aria-label': string;\n}\n\nexport type ActionProps = ButtonActionProps | ToggleActionProps;\n\ninterface SectionProps {\n title?: string;\n description?: string;\n children: React.ReactNode;\n actions?: ActionProps[];\n className?: string;\n}\n\nconst ButtonAction: React.FC<ButtonActionProps> = ({\n icon: Icon,\n className,\n label,\n onClick,\n disabled,\n variant,\n size,\n}) => (\n <Button\n onClick={onClick}\n disabled={disabled}\n variant={variant}\n size={size}\n className={cn('flex items-center gap-2 w-full sm:w-auto sm:min-w-fit', className)}\n aria-label={label}\n >\n {Icon && <Icon className=\"h-4 w-4 flex-shrink-0\" aria-hidden=\"true\" />}\n <span className=\"truncate\">{label}</span>\n </Button>\n);\n\nconst ToggleAction: React.FC<ToggleActionProps> = ({\n icon: Icon,\n className,\n label,\n 'aria-label': ariaLabel,\n pressed,\n onPressedChange,\n disabled,\n variant,\n size,\n}) => (\n <Toggle\n pressed={pressed}\n onPressedChange={onPressedChange}\n disabled={disabled}\n variant={variant === 'outline' ? 'outline' : 'default'}\n size={size === 'icon' || size === 'xs' ? 'sm' : size}\n className={cn('flex items-center gap-2', className)}\n aria-label={ariaLabel}\n >\n {Icon && <Icon className=\"h-4 w-4 flex-shrink-0\" aria-hidden=\"true\" />}\n {label && <span className=\"truncate\">{label}</span>}\n </Toggle>\n);\n\nexport function Section({\n title,\n description,\n children,\n actions,\n className,\n}: SectionProps): React.JSX.Element {\n const renderAction = (action: ActionProps, index: number) => {\n const key = `action-${index}`;\n return action.type === 'toggle' ? (\n <ToggleAction key={key} {...action} />\n ) : (\n <ButtonAction key={key} {...action} />\n );\n };\n\n return (\n <div className={cn('space-y-6', className)}>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex flex-col min-w-0 flex-1 space-y-2\">\n {title && (\n <h3\n className={cn(\n 'text-lg text-foreground text-(length:--font-size-subtitle) font-semibold mb-1 text-left',\n )}\n >\n {title}\n </h3>\n )}\n {description && (\n <p\n className={cn(\n 'text-sm text-muted-foreground text-left text-(length:--font-size-paragraph)',\n )}\n >\n {description}\n </p>\n )}\n </div>\n\n {actions && actions.length > 0 && (\n <div className=\"flex-shrink-0 flex items-start gap-2 mt-1\">\n {actions.map(renderAction)}\n </div>\n )}\n </div>\n\n <div className=\"space-y-6\">{children}</div>\n </div>\n );\n}\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/section.tsx"
},
{
"path": "src/components/ui/select.tsx",
"content": "import * as SelectPrimitive from '@radix-ui/react-select';\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nimport { Button } from './button';\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = 'default',\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: 'sm' | 'default';\n}) {\n return (\n <SelectPrimitive.Trigger data-slot=\"select-trigger\" data-size={size} asChild {...props}>\n <Button\n variant=\"outline\"\n className={cn(\n \"border-border/25 data-[placeholder]:text-primary text-input-foreground shadow-input-resting hover:shadow-input-hover hover:border-border/0 focus-within:outline-primary focus-within:shadow-input-hover bg-input disabled:bg-muted data-[state=open]:focus-within:outline-primary data-[state=open]:focus-within:shadow-input-hover [&_svg:not([class*='text-'])]:text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive flex w-full justify-between px-3 whitespace-nowrap ring-4 ring-transparent outline-4 disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n className,\n )}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon\n className={cn('text-primary size-4 transition-transform duration-200')}\n />\n </SelectPrimitive.Icon>\n </Button>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = 'popper',\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n className={cn(\n 'bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 shadow-bevel-xl data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 max-h-[var(--radix-select-content-available-height)] min-w-[var(--radix-select-trigger-width)] overflow-hidden rounded-3xl ring-0 duration-300 ease-in-out outline-none focus:outline-none',\n className,\n )}\n position={position}\n side=\"bottom\"\n align=\"start\"\n sideOffset={8}\n data-slot=\"select-content\"\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport className=\"p-1\">{children}</SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn('text-muted-foreground px-2 py-1.5 text-xs', className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n 'hover:bg-muted/50 focus:bg-muted data-[highlighted]:bg-muted/75 data-[state=checked]:bg-muted relative flex w-full items-center justify-between rounded-2xl px-2 py-1.5 text-sm outline-hidden select-none',\n className,\n )}\n {...props}\n >\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"text-primary size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn('bg-border pointer-events-none mx-1 my-1 h-px', className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn('flex cursor-default items-center justify-center py-1', className)}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn('flex cursor-default items-center justify-center py-1', className)}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n};\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/select.tsx"
},
{
"path": "src/components/ui/popover.tsx",
"content": "'use client';\n\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nfunction Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\n}\nfunction PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} asChild />;\n}\nfunction PopoverContent({\n className,\n align = 'center',\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Content>) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n data-slot=\"popover-content\"\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'bg-popover text-popover-foreground animate-in fade-in-0 zoom-in-95 shadow-bevel-xl data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) overflow-hidden rounded-3xl ring-0 outline-hidden duration-150 ease-in-out outline-none focus:outline-none',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n}\nfunction PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {\n return <PopoverPrimitive.Anchor data-slot=\"popover-anchor\" {...props} />;\n}\nexport { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/popover.tsx"
},
{
"path": "src/components/ui/sonner.tsx",
"content": "'use client';\n\nimport type { ToasterProps } from 'sonner';\nimport { Toaster as Sonner } from 'sonner';\n\nimport { useTheme } from '../../hooks/use-theme';\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n const { isDarkMode } = useTheme();\n const theme = isDarkMode ? 'dark' : 'light';\n\n return <Sonner theme={theme as ToasterProps['theme']} className=\"toaster group\" {...props} />;\n};\n\nexport { Toaster };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/sonner.tsx"
},
{
"path": "src/components/ui/spinner.tsx",
"content": "import type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nconst spinnerVariants = cva(\n 'inline-block h-8 w-8 animate-spin rounded-full border-2 border-transparent',\n {\n variants: {\n variant: {\n solid: '!border-t-current',\n dots: 'animate-[spin_5s_linear_infinite] border-6 border-dotted border-current',\n pulse: 'animate-pulse bg-current',\n },\n size: {\n sm: 'size-4',\n md: 'size-8',\n lg: 'size-12',\n },\n colorScheme: {\n primary: 'text-primary',\n foreground: 'text-primary-foreground',\n muted: 'text-muted-foreground',\n },\n },\n defaultVariants: {\n variant: 'solid',\n size: 'md',\n colorScheme: 'primary',\n },\n },\n);\n\nexport interface SpinnerProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof spinnerVariants> {}\n\nexport function Spinner({ variant, size, colorScheme, className, ...props }: SpinnerProps) {\n return (\n <div className={cn(spinnerVariants({ variant, size, colorScheme }), className)} {...props}>\n <span className=\"sr-only\">Loading...</span>\n </div>\n );\n}\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/spinner.tsx"
},
{
"path": "src/components/ui/switch.tsx",
"content": "'use client';\n\nimport * as SwitchPrimitive from '@radix-ui/react-switch';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nfunction Switch({ className, ...props }: React.ComponentProps<typeof SwitchPrimitive.Root>) {\n return (\n <SwitchPrimitive.Root\n data-slot=\"switch\"\n className={cn(\n 'theme-default:shadow-switch-resting data-[state=checked]:from-primary-foreground/0 data-[state=checked]:to-primary-foreground/25 from-primary-foreground/50 to-primary-foreground/0 bg-accent/50 hover:bg-accent/75 data-[state=checked]:hover:bg-primary theme-default:hover:shadow-switch-hover data-[state=checked]:bg-primary focus-visible:ring-ring focus-within:ring-ring relative h-7 w-[46px] rounded-full bg-gradient-to-l transition-all duration-150 ease-in-out focus-visible:ring-4 active:scale-95 disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n data-slot=\"switch-thumb\"\n className={cn(\n 'dark:bg-primary dark:shadow-switch-thumb-dark data-[state=checked]:dark:bg-background bg-background to-background/0 from-primary/5 shadow-switch-thumb data-[state=checked]:bg-background pointer-events-none absolute top-[4px] left-[4px] h-5 w-5 rounded-full bg-gradient-to-t transition-transform duration-150 ease-in-out data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0',\n )}\n />\n </SwitchPrimitive.Root>\n );\n}\n\nexport { Switch };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/switch.tsx"
},
{
"path": "src/components/ui/text-field.tsx",
"content": "import type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nconst textFieldVariants = cva(\n \"bg-input aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive relative box-border inline-flex w-full shrink-0 cursor-text items-center justify-center gap-2 overflow-hidden rounded-2xl text-sm transition-[color,box-shadow] duration-150 ease-in-out outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default:\n 'border-border/50 text-input-foreground shadow-input-resting hover:shadow-input-hover hover:border-primary/25 focus-within:border-border focus-within:ring-primary/15 focus-within:ring-4',\n error:\n 'border-destructive-border/50 text-destructive-foreground shadow-input-destructive-resting hover:shadow-input-destructive-hover hover:border-destructive-border/25 focus-within:ring-destructive-border/15 focus-within:ring-4',\n },\n size: {\n default: 'h-10',\n sm: 'h-9',\n lg: 'h-11',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport interface TextFieldProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n error?: boolean;\n helperText?: string;\n size?: VariantProps<typeof textFieldVariants>['size'];\n variant?: VariantProps<typeof textFieldVariants>['variant'];\n startAdornment?: React.ReactNode;\n endAdornment?: React.ReactNode;\n}\n\nconst TextField = React.forwardRef<HTMLInputElement, TextFieldProps>(\n (\n { className, variant, size, error, helperText, startAdornment, endAdornment, ...props },\n ref,\n ) => {\n const isDisabled = props.disabled;\n\n const WrapperComponent = props.id ? 'div' : 'label';\n\n return (\n <div className=\"flex w-full flex-col\">\n <WrapperComponent\n className={cn(\n textFieldVariants({ variant: error ? 'error' : variant, size }),\n 'group items-center gap-0.5',\n isDisabled &&\n 'bg-input-muted text-input-muted-foreground cursor-not-allowed opacity-50',\n isDisabled && variant === 'default' && 'bg-input-muted',\n startAdornment && 'pl-[5px]',\n endAdornment && 'pr-[5px]',\n className,\n )}\n >\n {startAdornment && (\n <div className=\"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\">\n {startAdornment}\n </div>\n )}\n <input\n className={cn(\n 'w-full flex-1 bg-transparent px-3 py-2 outline-none file:border-0 file:bg-transparent file:text-sm file:font-medium',\n isDisabled &&\n 'bg-input-muted text-input-muted-foreground cursor-not-allowed opacity-50',\n startAdornment && 'pl-0',\n endAdornment && 'pr-0',\n size === 'default' && 'h-10',\n size === 'sm' && 'h-9',\n size === 'lg' && 'h-11',\n )}\n ref={ref}\n {...props}\n />\n {endAdornment && (\n <div className=\"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\">\n {endAdornment}\n </div>\n )}\n </WrapperComponent>\n {helperText && (\n <p\n className={cn(\n 'mt-1.5 px-2 text-xs',\n error ? 'text-destructive-foreground' : 'text-muted-foreground',\n )}\n >\n {helperText}\n </p>\n )}\n </div>\n );\n },\n);\n\nTextField.displayName = 'TextField';\n\nexport { TextField, textFieldVariants };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/text-field.tsx"
},
{
"path": "src/components/ui/toast.tsx",
"content": "import { Flag } from 'lucide-react';\nimport type { ReactNode } from 'react';\nimport { toast, type ExternalToast } from 'sonner';\n\ntype ToastType = 'success' | 'info' | 'warning' | 'error';\n\ninterface ToastOptions {\n type: ToastType;\n message: string;\n className?: string;\n icon?: ReactNode;\n data?: ExternalToast;\n}\n\nconst colorClasses = {\n success: 'text-success-foreground',\n error: 'text-destructive-foreground',\n warning: 'text-warning-foreground',\n info: 'text-info-foreground',\n};\n\n/**\n * Show a toast notification with default styling and icons\n *\n * @param options - Toast configuration options\n * @returns The toast instance\n */\nexport const showToast = ({ type, message, className, icon, data = {} }: ToastOptions) => {\n const colorClass = colorClasses[type];\n const defaultIcon = <Flag className={`h-4 w-4 ${colorClass}`} />;\n\n const styledMessage = <span className={colorClass}>{message}</span>;\n\n const toastOptions: ExternalToast = {\n className,\n icon: icon || defaultIcon,\n ...data,\n };\n\n return toast[type](styledMessage, toastOptions);\n};\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/toast.tsx"
},
{
"path": "src/components/ui/toggle.tsx",
"content": "import { cva } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nconst toggleVariants = cva(\n \"hover:bg-muted hover:text-muted-foreground data-[state=on]:bg-accent data-[state=on]:text-accent-foreground focus-visible:border-ring aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive theme-default:shadow-bevel-sm focus-visible:ring-ring inline-flex items-center justify-center gap-2 rounded-xl text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none focus-visible:ring-3 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default:\n 'hover:bg-muted data-[state=on]:bg-muted data-[state=on]:text-primary bg-transparent',\n outline:\n 'data-[state=on]:bg-muted data-[state=on]:text-primary-foreground hover:bg-accent hover:text-accent-foreground shadow-input-resting bg-transparent',\n },\n size: {\n default: 'h-9 min-w-9 px-2',\n sm: 'h-8 min-w-8 px-1.5',\n lg: 'h-10 min-w-10 px-2.5',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport interface ToggleProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n pressed?: boolean;\n onPressedChange?: (pressed: boolean) => void;\n variant?: 'default' | 'outline';\n size?: 'sm' | 'default' | 'lg';\n}\n\nfunction ToggleRoot({\n className,\n children,\n pressed,\n onPressedChange,\n variant = 'default',\n size = 'default',\n ...props\n}: ToggleProps) {\n return (\n <button\n type=\"button\"\n aria-pressed={pressed}\n data-state={pressed ? 'on' : 'off'}\n data-variant={variant}\n onClick={() => onPressedChange?.(!pressed)}\n className={cn(toggleVariants({ variant, size }), className)}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nfunction Toggle(props: ToggleProps) {\n return <ToggleRoot {...props} />;\n}\n\nexport { Toggle };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/toggle.tsx"
},
{
"path": "src/components/ui/tooltip.tsx",
"content": "'use client';\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nconst tooltipVariants = cva(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 shadow-bevel-lg z-50 w-fit rounded-xl px-2 py-1 text-sm text-balance',\n {\n variants: {\n position: {\n top: 'origin-bottom',\n bottom: 'origin-top',\n left: 'origin-left',\n right: 'origin-right',\n },\n },\n defaultVariants: {\n position: 'top',\n },\n },\n);\n\nfunction Tooltip({ children, ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>) {\n return (\n <TooltipPrimitive.Provider>\n <TooltipPrimitive.Root {...props}>{children}</TooltipPrimitive.Root>\n </TooltipPrimitive.Provider>\n );\n}\n\nfunction TooltipTrigger({\n asChild = true,\n ...props\n}: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {\n return <TooltipPrimitive.Trigger asChild={asChild} {...props} />;\n}\n\ninterface TooltipContentProps\n extends React.ComponentProps<typeof TooltipPrimitive.Content>,\n VariantProps<typeof tooltipVariants> {}\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n TooltipContentProps\n>(({ className, side = 'top', position, sideOffset = 8, children, ...props }, ref) => {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n side={side}\n sideOffset={sideOffset}\n className={cn(tooltipVariants({ position: position || side }), className)}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"fill-popover\" />\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n );\n});\nTooltipContent.displayName = TooltipPrimitive.Content.displayName;\n\nexport { Tooltip, TooltipTrigger, TooltipContent, tooltipVariants };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/tooltip.tsx"
},
{
"path": "src/components/ui/separator.tsx",
"content": "import * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nfunction Separator({\n className,\n orientation = 'horizontal',\n decorative = true,\n ...props\n}: React.ComponentProps<'hr'> & { orientation?: 'horizontal' | 'vertical'; decorative?: boolean }) {\n return (\n <div\n data-slot=\"separator\"\n data-orientation={orientation}\n role={decorative ? 'none' : 'separator'}\n className={cn(\n 'bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Separator };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/separator.tsx"
},
{
"path": "src/components/ui/stepper.tsx",
"content": "'use client';\n\nimport { Check } from 'lucide-react';\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nimport { Card } from './card';\nimport { Separator } from './separator';\n\ninterface StepperContextValue {\n currentStep: number;\n isClickable: boolean;\n onStepClick?: (stepNumber: number, stepId?: string) => void;\n}\n\nconst StepperContext = React.createContext<StepperContextValue | null>(null);\n\nconst useStepperContext = () => {\n const context = React.useContext(StepperContext);\n if (!context) {\n throw new Error('Stepper components must be used within a Stepper');\n }\n return context;\n};\n\ninterface StepperProps {\n currentStep?: number;\n className?: string;\n onStepClick?: (stepNumber: number, stepId?: string) => void;\n enableAllSteps?: boolean;\n children: React.ReactNode;\n}\n\nfunction Stepper({\n currentStep = 0,\n className,\n onStepClick,\n enableAllSteps = false,\n children,\n}: StepperProps) {\n const contextValue: StepperContextValue = React.useMemo(\n () => ({\n currentStep,\n isClickable: enableAllSteps && !!onStepClick,\n onStepClick,\n }),\n [currentStep, enableAllSteps, onStepClick],\n );\n\n const processedChildren = React.useMemo(() => {\n const childArray = React.Children.toArray(children);\n const result: React.ReactNode[] = [];\n\n childArray.forEach((child, index) => {\n result.push(child);\n if (index < childArray.length - 1) {\n result.push(<StepSeparator key={`separator-${index}`} />);\n }\n });\n\n return result;\n }, [children]);\n\n return (\n <StepperContext.Provider value={contextValue}>\n <Card className={cn('w-full p-0', className)} data-slot=\"stepper\">\n <nav aria-label=\"Progress\" className=\"flex p-6 flex-col items-start gap-8 self-stretch\">\n <div className=\"flex items-center w-full\">{processedChildren}</div>\n </nav>\n </Card>\n </StepperContext.Provider>\n );\n}\n\ninterface StepProps {\n step: number;\n id?: string;\n hideNumber?: boolean;\n className?: string;\n children: React.ReactNode;\n onClick?: () => void;\n}\n\nfunction Step({ step, id, hideNumber = true, className, children, onClick }: StepProps) {\n const { currentStep, isClickable, onStepClick } = useStepperContext();\n\n const isCurrent = step === currentStep;\n const isCompleted = step < currentStep;\n const isClickableStep = isClickable && (isCompleted || isCurrent);\n\n const handleClick = () => {\n if (isClickableStep) {\n onClick?.();\n onStepClick?.(step, id);\n }\n };\n\n return (\n <div\n data-slot=\"stepper-step\"\n data-state={isCurrent ? 'current' : isCompleted ? 'completed' : 'pending'}\n data-step={step}\n className={cn(\n 'flex items-start',\n isClickableStep && 'cursor-pointer hover:opacity-80 transition-opacity',\n className,\n )}\n onClick={handleClick}\n role={isClickableStep ? 'button' : undefined}\n tabIndex={isClickableStep ? 0 : undefined}\n onKeyDown={\n isClickableStep\n ? (e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n handleClick();\n }\n }\n : undefined\n }\n >\n <div\n className={cn(\n 'flex items-center justify-center rounded-full transition-colors w-[21px] h-[21px] flex-shrink-0 mt-0.5',\n isCompleted\n ? 'bg-foreground text-background dark:bg-background dark:text-foreground border-0'\n : isCurrent\n ? 'border-2 border-primary bg-background text-primary'\n : 'bg-muted-foreground/30 border-0 text-muted-foreground',\n )}\n >\n {isCompleted ? (\n <Check className=\"w-3 h-3\" />\n ) : !hideNumber ? (\n <span className=\"text-xs font-medium\">{step + 1}</span>\n ) : null}\n </div>\n\n <div className=\"ml-2 flex-1\">{children}</div>\n </div>\n );\n}\n\ninterface StepTitleProps {\n className?: string;\n children: React.ReactNode;\n}\n\nfunction StepTitle({ className, children }: StepTitleProps) {\n return (\n <p\n data-slot=\"stepper-title\"\n className={cn(\n 'text-sm font-medium transition-colors whitespace-nowrap text-foreground',\n className,\n )}\n >\n {children}\n </p>\n );\n}\n\ninterface StepSeparatorProps {\n className?: string;\n}\n\nfunction StepSeparator({ className }: StepSeparatorProps) {\n return (\n <Separator\n orientation=\"horizontal\"\n className={cn('flex-1 mx-4', className)}\n data-slot=\"stepper-separator\"\n />\n );\n}\n\ninterface StepDescriptionProps {\n className?: string;\n children: React.ReactNode;\n}\n\nfunction StepDescription({ className, children }: StepDescriptionProps) {\n return (\n <p\n data-slot=\"stepper-description\"\n className={cn('text-xs text-muted-foreground mt-1', className)}\n >\n {children}\n </p>\n );\n}\n\nexport { Stepper, Step, StepTitle, StepSeparator, StepDescription };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/stepper.tsx"
},
{
"path": "src/components/ui/wizard.tsx",
"content": "'use client';\n\nimport * as React from 'react';\n\nimport { cn } from '../../lib/theme-utils';\n\nimport { Card, CardContent } from './card';\nimport { FormActions } from './form-actions';\nimport { Spinner } from './spinner';\nimport { WizardStepper } from './wizard-stepper';\n\nexport interface StepFormActions {\n showPrevious?: boolean;\n showNext?: boolean;\n onPreviousAction?: (stepId: string) => Promise<boolean> | boolean;\n onNextAction?: (stepId: string) => Promise<boolean> | boolean;\n}\n\nexport interface WizardStep {\n id: string;\n title: string;\n description?: string;\n content: React.ComponentType<StepProps>;\n actions?: StepFormActions;\n}\n\nexport interface StepProps {\n onPrevious?: () => void;\n onNext?: () => void;\n isLoading?: boolean;\n}\n\nexport interface FormActionLabels {\n nextButtonLabel?: string;\n previousButtonLabel?: string;\n completeButtonLabel?: string;\n}\n\nexport interface WizardProps {\n steps: WizardStep[];\n initialStep?: number;\n onComplete?: () => Promise<void> | void;\n className?: string;\n formActionLabels?: FormActionLabels;\n hideStepperNumbers?: boolean;\n isLoading?: boolean;\n allowStepNavigation?: boolean;\n}\n\nfunction Wizard({\n steps,\n initialStep = 0,\n onComplete,\n className,\n formActionLabels,\n hideStepperNumbers = false,\n isLoading = false,\n allowStepNavigation = true,\n}: WizardProps) {\n const [activeStep, setActiveStep] = React.useState(initialStep);\n\n const currentStepConfig = steps[activeStep];\n const isFirstStep = activeStep === 0;\n const isLastStep = activeStep === steps.length - 1;\n\n const handleNext = React.useCallback(async () => {\n if (isLoading) return;\n\n const step = steps[activeStep];\n\n if (step?.actions?.onNextAction) {\n const canProceed = await step.actions.onNextAction(step.id);\n if (!canProceed) {\n return;\n }\n }\n\n if (isLastStep) {\n await onComplete?.();\n } else {\n setActiveStep((prev) => prev + 1);\n }\n }, [activeStep, isLastStep, steps, onComplete, isLoading]);\n\n const handlePrevious = React.useCallback(async () => {\n if (isFirstStep) return;\n\n const step = steps[activeStep];\n\n if (step?.actions?.onPreviousAction) {\n const canProceed = await step.actions.onPreviousAction(step.id);\n if (!canProceed) {\n return;\n }\n }\n\n setActiveStep((prev) => prev - 1);\n }, [activeStep, isFirstStep, steps]);\n\n const handleStepClick = React.useCallback(\n async (stepIndex: number) => {\n if (isLoading || !allowStepNavigation) return;\n\n // Only allow navigation to previous steps or the current step\n if (stepIndex > activeStep) return;\n\n setActiveStep(stepIndex);\n },\n [activeStep, isLoading, allowStepNavigation],\n );\n\n const CurrentStepComponent = currentStepConfig?.content;\n const showPrevious = currentStepConfig?.actions?.showPrevious !== false && !isFirstStep;\n const showNext = currentStepConfig?.actions?.showNext ?? true;\n\n const labels = {\n nextButtonLabel: 'Next',\n previousButtonLabel: 'Previous',\n completeButtonLabel: 'Submit',\n ...formActionLabels,\n };\n\n return (\n <div className={cn('space-y-6', className)}>\n <WizardStepper\n steps={steps}\n currentStep={activeStep}\n hideNumbers={hideStepperNumbers}\n onStepClick={allowStepNavigation ? handleStepClick : undefined}\n />\n\n <Card>\n <CardContent className=\"relative\">\n {isLoading && (\n <div className=\"absolute inset-0 bg-white/50 flex items-center justify-center z-10\">\n <Spinner />\n </div>\n )}\n <div className={cn(isLoading && 'opacity-50 pointer-events-none')}>\n {CurrentStepComponent ? (\n <CurrentStepComponent\n onNext={handleNext}\n onPrevious={handlePrevious}\n isLoading={isLoading}\n />\n ) : null}\n </div>\n </CardContent>\n </Card>\n\n <FormActions\n isLoading={isLoading}\n showPrevious={showPrevious}\n showNext={showNext}\n nextAction={{\n type: 'button',\n label: isLastStep ? labels.completeButtonLabel : labels.nextButtonLabel,\n variant: 'primary',\n onClick: handleNext,\n }}\n previousAction={{\n type: 'button',\n label: labels.previousButtonLabel,\n variant: 'outline',\n onClick: handlePrevious,\n }}\n />\n </div>\n );\n}\n\nexport { Wizard };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/wizard.tsx"
},
{
"path": "src/components/ui/wizard-stepper.tsx",
"content": "'use client';\n\nimport { Stepper, Step, StepTitle, StepDescription } from './stepper';\n\nexport interface WizardStep {\n id?: string;\n title: string;\n description?: string;\n}\n\ninterface WizardStepperProps {\n steps: WizardStep[];\n currentStep?: number;\n onStepClick?: (stepIndex: number, stepId?: string) => void;\n className?: string;\n hideNumbers?: boolean;\n}\n\nfunction WizardStepper({\n steps,\n currentStep = 0,\n onStepClick,\n className,\n hideNumbers = true,\n}: WizardStepperProps) {\n return (\n <Stepper\n currentStep={currentStep}\n enableAllSteps={!!onStepClick}\n onStepClick={onStepClick}\n className={className}\n >\n {steps.map((step, index) => (\n <Step key={step.id || index} step={index} id={step.id} hideNumber={hideNumbers}>\n <StepTitle className=\"text-(length:--font-size-label)\">{step.title}</StepTitle>\n {step.description && <StepDescription>{step.description}</StepDescription>}\n </Step>\n ))}\n </Stepper>\n );\n}\n\nexport { WizardStepper };\nexport type { WizardStepperProps };\n",
"type": "registry:component",
"target": "auth0-ui-components/components/ui/wizard-stepper.tsx"
},
{
"path": "src/hooks/use-translator.ts",
"content": "import { type EnhancedTranslationFunction } from '@auth0/universal-components-core';\nimport { useMemo, useCallback } from 'react';\n\nimport { useCoreClient } from './use-core-client';\n\n/**\n * Custom hook for accessing the i18n service from CoreClient.\n *\n * This hook provides access to the i18n service from the CoreClient context,\n * including enhanced translation functions with Trans component support and language change capabilities.\n *\n * @param namespace - The translation namespace (e.g., 'mfa', 'common')\n * @param overrides - Optional translation overrides for the namespace\n * @returns An object containing the enhanced translator function and changeLanguage function\n *\n * @example\n * ```tsx\n * // Basic usage with namespace only\n * const { t, changeLanguage } = useTranslator('common');\n *\n * // Usage with overrides\n * const { t } = useTranslator('mfa', {\n * title: 'Custom Title',\n * 'sms.title': 'Text Message'\n * });\n *\n * // Using the basic translator\n * const title = t('title');\n * const message = t('welcome', { name: 'John' });\n *\n * // Using the trans method for safe HTML rendering\n * const elements = t.trans('help.message', {\n * components: {\n * link: (children) => <a href=\"/help\" target=\"_blank\">{children}</a>,\n * strong: (children) => <strong>{children}</strong>\n * },\n * vars: { name: 'John' }\n * });\n *\n * // Render the elements\n * return (\n * <div>\n * {elements.map((element, index) => (\n * <Fragment key={index}>{element}</Fragment>\n * ))}\n * </div>\n * );\n *\n * // Changing language\n * await changeLanguage('es-ES');\n * ```\n */\nexport function useTranslator(\n namespace: string,\n overrides?: Record<string, unknown>,\n): {\n t: EnhancedTranslationFunction;\n changeLanguage: (language: string, fallbackLanguage?: string) => Promise<void>;\n currentLanguage: string;\n fallbackLanguage: string | undefined;\n} {\n const { coreClient } = useCoreClient();\n\n if (!coreClient) {\n throw new Error(\n 'useTranslator must be used within Auth0ComponentProvider with initialized CoreClient',\n );\n }\n\n const translator = useMemo(() => {\n return coreClient.i18nService.translator(namespace, overrides);\n }, [coreClient, namespace, overrides]);\n\n const changeLanguage = useCallback(\n async (language: string, fallbackLanguage?: string) => {\n await coreClient.i18nService.changeLanguage(language, fallbackLanguage);\n },\n [coreClient],\n );\n\n return {\n t: translator,\n changeLanguage,\n currentLanguage: coreClient.i18nService.currentLanguage,\n fallbackLanguage: coreClient.i18nService.fallbackLanguage,\n };\n}\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/use-translator.ts"
},
{
"path": "src/hooks/use-core-client.ts",
"content": "import type { CoreClientInterface } from '@auth0/universal-components-core';\nimport * as React from 'react';\n\nconst CoreClientContext = React.createContext<{\n coreClient: CoreClientInterface | null;\n}>({\n coreClient: null,\n});\n\n/**\n * Hook to access the CoreClient instance from context.\n *\n * Provides access to the initialized CoreClient which handles API calls and business logic.\n *\n * @returns {{ coreClient: CoreClientInterface | null }} The current CoreClient instance or null if not initialized.\n *\n * @throws {Error} Throws if used outside of an Auth0ComponentProvider.\n */\nexport const useCoreClient = () => {\n const context = React.useContext(CoreClientContext);\n if (!context) {\n throw new Error('useCoreClient must be used within Auth0ComponentProvider');\n }\n return context;\n};\n\nexport { CoreClientContext };\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/use-core-client.ts"
},
{
"path": "src/hooks/use-core-client-initialization.ts",
"content": "import type {\n CoreClientInterface,\n AuthDetails,\n I18nInitOptions,\n} from '@auth0/universal-components-core';\nimport { createCoreClient } from '@auth0/universal-components-core';\nimport * as React from 'react';\n\ninterface UseCoreClientInitializationProps {\n authDetails: AuthDetails;\n i18nOptions?: I18nInitOptions;\n}\n\n/**\n * Custom hook to handle CoreClient initialization\n */\nexport const useCoreClientInitialization = ({\n authDetails,\n i18nOptions,\n}: UseCoreClientInitializationProps) => {\n const [coreClient, setCoreClient] = React.useState<CoreClientInterface | null>(null);\n const { domain, authProxyUrl } = authDetails;\n\n React.useEffect(() => {\n const initializeCoreClient = async () => {\n try {\n const initializedCoreClient = await createCoreClient(authDetails, i18nOptions);\n setCoreClient(initializedCoreClient);\n } catch (error) {\n console.error(error);\n }\n };\n initializeCoreClient();\n }, [domain, authProxyUrl, i18nOptions]);\n\n return coreClient;\n};\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/use-core-client-initialization.ts"
},
{
"path": "src/hooks/use-theme.ts",
"content": "'use client';\n\nimport { useContext } from 'react';\n\nimport { ThemeContext } from '../providers/theme-provider';\n\n/**\n * useTheme\n *\n * Access the current theme from context. Includes:\n * - mode\n * - styling (CSS variables)\n */\nexport function useTheme() {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/use-theme.ts"
},
{
"path": "src/hooks/use-scope-manager.ts",
"content": "import { createContext, useContext } from 'react';\n\nexport type Audience = 'me' | 'my-org';\n\nexport interface ScopeManagerContextValue {\n registerScopes: (audience: Audience, scopes: string) => void;\n isReady: boolean;\n ensured: Record<Audience, string>;\n}\n\nexport const ScopeManagerContext = createContext<ScopeManagerContextValue>({\n registerScopes: () => {},\n isReady: false,\n ensured: { me: '', 'my-org': '' },\n});\n\nexport const useScopeManager = () => useContext(ScopeManagerContext);\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/use-scope-manager.ts"
},
{
"path": "src/hooks/my-organization/idp-management/use-sso-provider-create.ts",
"content": "import {\n hasApiErrorBody,\n SsoProviderMappers,\n type CreateIdentityProviderRequestContent,\n type CreateIdentityProviderRequestContentPrivate,\n type IdentityProvider,\n} from '@auth0/universal-components-core';\nimport { useCallback, useState } from 'react';\n\nimport { showToast } from '../../../components/ui/toast';\nimport { useCoreClient } from '../../../hooks/use-core-client';\nimport { useTranslator } from '../../../hooks/use-translator';\nimport type { UseSsoProviderCreateOptions } from '../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\n\nexport interface UseSsoProviderCreateReturn {\n createProvider: (data: CreateIdentityProviderRequestContentPrivate) => Promise<void>;\n isCreating: boolean;\n}\n\nexport function useSsoProviderCreate({\n createAction,\n customMessages = {},\n}: UseSsoProviderCreateOptions = {}): UseSsoProviderCreateReturn {\n const { coreClient } = useCoreClient();\n const { t } = useTranslator('idp_management.create_sso_provider', customMessages);\n const [isCreating, setIsCreating] = useState(false);\n\n const createProvider = useCallback(\n async (data: CreateIdentityProviderRequestContentPrivate): Promise<void> => {\n if (!coreClient) {\n return;\n }\n setIsCreating(true);\n\n try {\n if (createAction?.onBefore) {\n const canProceed = createAction.onBefore(data);\n if (!canProceed) {\n return;\n }\n }\n\n const { strategy, name, display_name, ...configOptions } = data;\n\n const formData = {\n strategy,\n name,\n display_name,\n options: configOptions,\n };\n\n const apiRequestData: CreateIdentityProviderRequestContent =\n SsoProviderMappers.createToAPI(formData);\n\n const result: IdentityProvider = await coreClient\n .getMyOrganizationApiClient()\n .organization.identityProviders.create(apiRequestData);\n\n showToast({\n type: 'success',\n message: t('notifications.provider_create_success', { providerName: result.name }),\n });\n\n createAction?.onAfter?.(data, result);\n } catch (error) {\n if (\n hasApiErrorBody(error) &&\n error.body?.status === 409 &&\n error.body?.type === 'https://auth0.com/api-errors#A0E-409-0001'\n ) {\n showToast({\n type: 'error',\n message: t('notifications.provider_create_duplicated_provider_error', {\n providerName: data.name,\n }),\n });\n } else {\n showToast({\n type: 'error',\n message: t('notifications.general_error'),\n });\n }\n } finally {\n setIsCreating(false);\n }\n },\n [coreClient, createAction, t],\n );\n\n return {\n createProvider,\n isCreating,\n };\n}\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/my-organization/idp-management/use-sso-provider-create.ts"
},
{
"path": "src/hooks/my-organization/idp-management/use-provider-form-mode.ts",
"content": "import { useMemo } from 'react';\n\nimport type { FormMode } from '../../../types/my-organization/idp-management/sso-provider/sso-provider-create-types';\n\n/**\n * Custom hook to determine provider form behavior based on mode\n * @param mode - The form mode ('create' | 'edit')\n * @returns Object containing form mode configuration\n */\nexport const useProviderFormMode = (mode: FormMode = 'create') => {\n return useMemo(\n () => ({\n showCopyButtons: mode === 'edit',\n }),\n [mode],\n );\n};\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/my-organization/idp-management/use-provider-form-mode.ts"
},
{
"path": "src/providers/proxy-provider.tsx",
"content": "'use client';\n\nimport * as React from 'react';\n\nimport { Toaster } from '../components/ui/sonner';\nimport { Spinner } from '../components/ui/spinner';\nimport { CoreClientContext } from '../hooks/use-core-client';\nimport { useCoreClientInitialization } from '../hooks/use-core-client-initialization';\nimport type { Auth0ComponentProviderProps } from '../types/auth-types';\n\nimport { ScopeManagerProvider } from './scope-manager-provider';\nimport { ThemeProvider } from './theme-provider';\n\n/**\n * Auth0 Proxy Provider for Next.js and server-side authentication\n *\n * Use this when you have a backend proxy that handles Auth0 authentication.\n *\n * @example\n * ```tsx\n * <Auth0ProxyProvider\n * authDetails={{ authProxyUrl: '/api/auth' }}\n * themeSettings={{ mode: 'dark', theme: 'rounded' }}\n * >\n * <YourApp />\n * </Auth0ProxyProvider>\n * ```\n */\nexport const Auth0ComponentProvider = ({\n i18n,\n authDetails,\n themeSettings = {\n theme: 'default',\n mode: 'light',\n variables: {\n common: {},\n light: {},\n dark: {},\n },\n },\n loader,\n children,\n}: Auth0ComponentProviderProps & { children: React.ReactNode }) => {\n const memoizedAuthDetails = React.useMemo(\n () => ({\n ...authDetails,\n contextInterface: undefined,\n }),\n [authDetails],\n );\n\n const coreClient = useCoreClientInitialization({\n authDetails: memoizedAuthDetails,\n i18nOptions: i18n,\n });\n\n const coreClientValue = React.useMemo(\n () => ({\n coreClient,\n }),\n [coreClient],\n );\n\n return (\n <ThemeProvider\n themeSettings={{\n mode: themeSettings.mode,\n variables: themeSettings.variables,\n loader,\n theme: themeSettings.theme,\n }}\n >\n <Toaster position=\"top-right\" />\n <React.Suspense\n fallback={\n loader || (\n <div className=\"flex items-center justify-center min-h-[200px]\">\n <Spinner />\n </div>\n )\n }\n >\n <CoreClientContext.Provider value={coreClientValue}>\n <ScopeManagerProvider>{children}</ScopeManagerProvider>\n </CoreClientContext.Provider>\n </React.Suspense>\n </ThemeProvider>\n );\n};\n\nexport default Auth0ComponentProvider;\n",
"type": "registry:file",
"target": "auth0-ui-components/providers/proxy-provider.tsx"
},
{
"path": "src/providers/spa-provider.tsx",
"content": "'use client';\n\nimport { useAuth0 } from '@auth0/auth0-react';\nimport type { BasicAuth0ContextInterface } from '@auth0/universal-components-core';\nimport * as React from 'react';\n\nimport { Toaster } from '../components/ui/sonner';\nimport { Spinner } from '../components/ui/spinner';\nimport { CoreClientContext } from '../hooks/use-core-client';\nimport { useCoreClientInitialization } from '../hooks/use-core-client-initialization';\nimport type { Auth0ComponentProviderProps } from '../types/auth-types';\n\nimport { ScopeManagerProvider } from './scope-manager-provider';\nimport { ThemeProvider } from './theme-provider';\n\nexport const Auth0ComponentProvider = ({\n i18n,\n authDetails,\n themeSettings = {\n theme: 'default',\n mode: 'light',\n variables: {\n common: {},\n light: {},\n dark: {},\n },\n },\n loader,\n children,\n}: Auth0ComponentProviderProps & { children: React.ReactNode }) => {\n const auth0ReactContext = useAuth0();\n\n const auth0ContextInterface = React.useMemo(() => {\n if (auth0ReactContext && 'isAuthenticated' in auth0ReactContext) {\n return auth0ReactContext as BasicAuth0ContextInterface;\n }\n\n if (authDetails?.contextInterface) {\n return authDetails.contextInterface;\n }\n\n throw new Error(\n 'Auth0ContextInterface is not available. Make sure you wrap your app with Auth0Provider from @auth0/auth0-react, or pass a contextInterface via authDetails.',\n );\n }, [auth0ReactContext, authDetails?.contextInterface]);\n\n const memoizedAuthDetails = React.useMemo(\n () => ({\n ...authDetails,\n contextInterface: auth0ContextInterface,\n }),\n [authDetails, auth0ContextInterface],\n );\n\n const coreClient = useCoreClientInitialization({\n authDetails: memoizedAuthDetails,\n i18nOptions: i18n,\n });\n\n const coreClientValue = React.useMemo(\n () => ({\n coreClient,\n }),\n [coreClient],\n );\n\n return (\n <ThemeProvider\n themeSettings={{\n mode: themeSettings.mode,\n variables: themeSettings.variables,\n loader,\n theme: themeSettings.theme,\n }}\n >\n <Toaster position=\"top-right\" />\n <React.Suspense\n fallback={\n loader || (\n <div className=\"flex items-center justify-center min-h-[200px]\">\n <Spinner />\n </div>\n )\n }\n >\n <CoreClientContext.Provider value={coreClientValue}>\n <ScopeManagerProvider>{children}</ScopeManagerProvider>\n </CoreClientContext.Provider>\n </React.Suspense>\n </ThemeProvider>\n );\n};\n\nexport default Auth0ComponentProvider;\n",
"type": "registry:file",
"target": "auth0-ui-components/providers/spa-provider.tsx"
},
{
"path": "src/providers/theme-provider.tsx",
"content": "'use client';\n\nimport { applyStyleOverrides, type StylingVariables } from '@auth0/universal-components-core';\nimport * as React from 'react';\n\nimport type { ThemeContextValue, ThemeInput } from '../types/theme-types';\n\n/**\n * Default empty customer overrides. (later may be UL branding)\n */\nconst defaultStyleOverrides: StylingVariables = { common: {}, light: {}, dark: {} };\n\n/**\n * ThemeContext\n *\n * Provides access to customer overrides and a merged theme object for convenience.\n */\nexport const ThemeContext = React.createContext<ThemeContextValue>({\n isDarkMode: false,\n variables: defaultStyleOverrides,\n loader: null,\n});\n\n/**\n * ThemeProvider\n *\n * Provides theme configuration via React Context to all components in the tree.\n * It merges optional styling overrides (CSS variables).\n *\n * @param themeSettings - Optional styling overrides\n * @param children - The components that will have access to the theme\n *\n * @example\n * ```tsx\n * <ThemeProvider\n * themeSettings={{\n * theme: \"default\" | \"minimal\" | \"rounded\";\n * mode: 'dark',\n * variables: {\n * common: {\n * \"--font-size-heading\": \"1.5rem\",\n * \"--font-size-title\": \"1.25rem\",\n * },\n * light: {\n * \"--color-primary\": \"blue\",\n * },\n * dark: {\n * \"--color-primary\": \"red\",\n * },\n * },\n * loader: <CustomSpinner />\n * }}\n * >\n * <App />\n * </ThemeProvider>\n * ```\n */\nexport const ThemeProvider: React.FC<{\n themeSettings?: ThemeInput;\n children: React.ReactNode;\n}> = ({ themeSettings, children }) => {\n const { variables, loader, mode, theme } = React.useMemo(\n () => ({\n variables: themeSettings?.variables ?? defaultStyleOverrides,\n loader: themeSettings?.loader ?? null,\n mode: themeSettings?.mode,\n theme: themeSettings?.theme,\n }),\n [themeSettings],\n );\n\n React.useEffect(() => {\n applyStyleOverrides(variables, mode, theme);\n }, [variables, mode, theme]);\n\n return (\n <ThemeContext.Provider value={{ isDarkMode: mode === 'dark', variables, loader }}>\n {children}\n </ThemeContext.Provider>\n );\n};\n",
"type": "registry:file",
"target": "auth0-ui-components/providers/theme-provider.tsx"
},
{
"path": "src/providers/scope-manager-provider.tsx",
"content": "import React, { useState, useCallback, useEffect, type ReactNode } from 'react';\n\nimport { useCoreClient } from '../hooks/use-core-client';\nimport { ScopeManagerContext, type Audience } from '../hooks/use-scope-manager';\n\nexport const ScopeManagerProvider: React.FC<{ children: ReactNode }> = ({ children }) => {\n const { coreClient } = useCoreClient();\n\n const [scopeRegistry, setScopeRegistry] = useState<Record<Audience, Set<string>>>(() => ({\n me: new Set(),\n 'my-org': new Set(),\n }));\n\n const [ensured, setEnsured] = useState<Record<Audience, string>>({\n me: '',\n 'my-org': '',\n });\n\n const [isReady, setIsReady] = useState(false);\n\n const registerScopes = useCallback((audience: Audience, scopes: string) => {\n if (!scopes?.trim()) return;\n\n const newScopes = scopes\n .split(/\\s+/)\n .map((s) => s.trim())\n .filter(Boolean);\n\n if (newScopes.length === 0) return;\n\n setScopeRegistry((currentRegistry) => {\n const audienceSet = currentRegistry[audience];\n let changed = false;\n const nextAudienceSet = new Set(audienceSet);\n\n newScopes.forEach((scope) => {\n if (!nextAudienceSet.has(scope)) {\n nextAudienceSet.add(scope);\n changed = true;\n }\n });\n\n if (changed) {\n return {\n ...currentRegistry,\n [audience]: nextAudienceSet,\n };\n }\n return currentRegistry;\n });\n }, []);\n\n useEffect(() => {\n if (!coreClient) return;\n\n const ensureAllScopesSequential = async () => {\n let hasScopes = false;\n let anyUpdated = false;\n\n for (const audience of ['me', 'my-org'] as const) {\n const scopes = Array.from(scopeRegistry[audience]).sort();\n const scopeString = scopes.join(' ');\n\n if (scopes.length > 0 && scopeString.trim()) {\n hasScopes = true;\n\n if (scopeString !== ensured[audience]) {\n try {\n await coreClient.ensureScopes(scopeString, audience);\n anyUpdated = true;\n } catch (error) {\n console.error(`Failed to ensure scopes for ${audience}: ${scopeString}`, error);\n }\n }\n }\n }\n\n // Update ensured state to match current registry\n if (anyUpdated) {\n setEnsured({\n me: Array.from(scopeRegistry.me).sort().join(' '),\n 'my-org': Array.from(scopeRegistry['my-org']).sort().join(' '),\n });\n }\n\n setIsReady(hasScopes);\n };\n\n ensureAllScopesSequential();\n }, [coreClient, scopeRegistry, ensured]);\n\n const contextValue = React.useMemo(\n () => ({ registerScopes, isReady, ensured }),\n [registerScopes, isReady, ensured],\n );\n\n return (\n <ScopeManagerContext.Provider value={contextValue}>{children}</ScopeManagerContext.Provider>\n );\n};\n",
"type": "registry:file",
"target": "auth0-ui-components/providers/scope-manager-provider.tsx"
},
{
"path": "src/hooks/my-organization/config/use-config.tsx",
"content": "import {\n AVAILABLE_STRATEGY_LIST,\n hasApiErrorBody,\n type GetConfigurationResponseContent,\n type IdpStrategy,\n} from '@auth0/universal-components-core';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\n\nimport type { UseConfigResult } from '../../../types/my-organization/config/config-types';\nimport { useCoreClient } from '../../use-core-client';\n\nexport function useConfig(): UseConfigResult {\n const { coreClient } = useCoreClient();\n const [config, setConfig] = useState<GetConfigurationResponseContent | null>(null);\n const [isLoadingConfig, setIsLoadingConfig] = useState(false);\n const [isConfigValid, setIsConfigValid] = useState(true);\n\n const fetchConfig = useCallback(async (): Promise<void> => {\n if (!coreClient) {\n return;\n }\n setIsLoadingConfig(true);\n\n try {\n const result: GetConfigurationResponseContent = await coreClient\n .getMyOrganizationApiClient()\n .organization.configuration.get();\n setConfig(result);\n\n // Validate the config after fetching\n const hasAllowedStrategies =\n result.allowed_strategies && result.allowed_strategies.length > 0;\n setIsConfigValid(!!hasAllowedStrategies);\n } catch (error) {\n // If config is not set\n if (hasApiErrorBody(error) && error.body?.status === 404) {\n setConfig(null);\n setIsConfigValid(false);\n }\n } finally {\n setIsLoadingConfig(false);\n }\n }, [coreClient]);\n\n const filteredStrategies = useMemo((): IdpStrategy[] => {\n const allowedStrategies = config?.allowed_strategies;\n\n if (!allowedStrategies) {\n return AVAILABLE_STRATEGY_LIST;\n }\n\n return AVAILABLE_STRATEGY_LIST.filter((strategy) => allowedStrategies.includes(strategy));\n }, [config]);\n\n const shouldAllowDeletion = useMemo((): boolean => {\n return (\n config?.connection_deletion_behavior === 'allow' ||\n config?.connection_deletion_behavior === 'allow_if_empty'\n );\n }, [config]);\n\n // Fetch config on mount\n useEffect(() => {\n fetchConfig();\n }, []);\n\n return {\n config,\n isLoadingConfig,\n fetchConfig,\n filteredStrategies,\n shouldAllowDeletion,\n isConfigValid,\n };\n}\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/my-organization/config/use-config.tsx"
},
{
"path": "src/hooks/my-organization/config/use-idp-config.tsx",
"content": "import { hasApiErrorBody, type IdpStrategy } from '@auth0/universal-components-core';\nimport { useCallback, useEffect, useState } from 'react';\n\nimport type {\n IdpConfig,\n UseConfigIdpResult,\n} from '../../../types/my-organization/config/config-idp-types';\nimport { useCoreClient } from '../../use-core-client';\n\nexport function useIdpConfig(): UseConfigIdpResult {\n const { coreClient } = useCoreClient();\n const [idpConfig, setIdpConfig] = useState<IdpConfig | null>(null);\n const [isLoadingIdpConfig, setIsLoadingIdpConfig] = useState(false);\n const [isIdpConfigValid, setIsIdpConfigValid] = useState(true);\n\n const fetchIdpConfig = useCallback(async (): Promise<void> => {\n if (!coreClient) {\n return;\n }\n setIsLoadingIdpConfig(true);\n\n try {\n const result = (await coreClient\n .getMyOrganizationApiClient()\n .organization.configuration.identityProviders.get()) as unknown as IdpConfig;\n\n setIdpConfig(result);\n\n // Validate the idpConfig after fetching\n const hasStrategies = result.strategies && Object.keys(result.strategies).length > 0;\n setIsIdpConfigValid(!!hasStrategies);\n } catch (error) {\n // If config is not set\n if (hasApiErrorBody(error) && error.body?.status === 404) {\n setIdpConfig(null);\n setIsIdpConfigValid(false);\n }\n } finally {\n setIsLoadingIdpConfig(false);\n }\n }, [coreClient]);\n\n const isProvisioningEnabled = useCallback(\n (strategy: IdpStrategy | undefined): boolean => {\n if (!strategy || !idpConfig?.strategies?.[strategy]) {\n return false;\n }\n return idpConfig.strategies[strategy].enabled_features.includes('provisioning');\n },\n [idpConfig],\n );\n\n const isProvisioningMethodEnabled = useCallback(\n (strategy: IdpStrategy | undefined): boolean => {\n if (!strategy || !idpConfig?.strategies?.[strategy]) {\n return false;\n }\n return idpConfig.strategies[strategy].provisioning_methods.includes('scim');\n },\n [idpConfig],\n );\n\n // Fetch config on mount\n useEffect(() => {\n fetchIdpConfig();\n }, []);\n\n return {\n idpConfig,\n isLoadingIdpConfig,\n fetchIdpConfig,\n isProvisioningEnabled,\n isProvisioningMethodEnabled,\n isIdpConfigValid,\n };\n}\n",
"type": "registry:hook",
"target": "auth0-ui-components/hooks/my-organization/config/use-idp-config.tsx"
},
{
"path": "src/components/my-organization/idp-management/sso-provider-create/provider-configure/common-configure-fields.tsx",
"content": "import { useFormContext } from 'react-hook-form';\n\nimport { useTranslator } from '../../../../../hooks/use-translator';\nimport type { IdpConfig } from '../../../../../types/my-organization/config/config-idp-types';\nimport { Checkbox } from '../../../../ui/checkbox';\nimport { FormField, FormItem, FormLabel, FormControl, FormDescription } from '../../../../ui/form';\n\ninterface CommonConfigureFieldsProps {\n idpConfig: IdpConfig | null;\n readOnly?: boolean;\n customMessages?: Partial<Record<string, unknown>>;\n}\n\n/**\n * CommonConfigureFields Component\n * Renders common fields (show_as_button, assign_membership_on_login) that are shared across all SSO provider strategies\n */\nexport function CommonConfigureFields({\n idpConfig,\n readOnly = false,\n customMessages = {},\n}: CommonConfigureFieldsProps) {\n const { t } = useTranslator(\n 'idp_management.create_sso_provider.provider_configure',\n customMessages,\n );\n\n const form = useFormContext();\n\n // Only show these fields if the config allows them\n const showAsButtonEnabled = idpConfig?.organization?.can_set_show_as_button;\n const assignMembershipEnabled = idpConfig?.organization?.can_set_assign_membership_on_login;\n\n // If neither field is enabled, don't render anything\n if (!showAsButtonEnabled && !assignMembershipEnabled) {\n return null;\n }\n\n return (\n <div className=\"space-y-6 pt-4\">\n {showAsButtonEnabled && (\n <FormField\n control={form.control}\n name=\"show_as_button\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <Checkbox\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={readOnly}\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel className=\"text-sm font-normal\">\n {t('fields.common.show_as_button.label')}\n </FormLabel>\n <FormDescription className=\"text-sm\">\n {t('fields.common.show_as_button.helper_text')}\n </FormDescription>\n </div>\n </FormItem>\n )}\n />\n )}\n\n {assignMembershipEnabled && (\n <FormField\n control={form.control}\n name=\"assign_membership_on_login\"\n render={({ field }) => (\n <FormItem className=\"flex flex-row items-start space-x-3 space-y-0\">\n <FormControl>\n <Checkbox\n checked={field.value}\n onCheckedChange={field.onChange}\n disabled={readOnly}\n />\n </FormControl>\n <div className=\"space-y-1 leading-none\">\n <FormLabel className=\"text-sm font-normal\">\n {t('fields.common.assign_membership_on_login.label')}\n </FormLabel>\n <FormDescription className=\"text-sm\">\n {t('fields.common.assign_membership_on_login.helper_text')}\n </FormDescription>\n </div>\n </FormItem>\n )}\n />\n )}\n </div>\n );\n}\n",
"type": "registry:component",
"target": "auth0-ui-components/components/my-organization/idp-management/sso-provider-create/provider-configure/common-configure-fields.tsx"
},
{
"path": "src/types/my-organization/idp-management/sso-provider/sso-provider-create-types.ts",
"content": "import type {\n SharedComponentProps,\n ProviderSelectMessages,\n ProviderDetailsMessages,\n IdpStrategy,\n ProviderSelectionFormValues,\n IdentityProvider,\n ProviderConfigureMessages,\n ProviderConfigureFieldsMessages,\n SsoProviderCreateMessages,\n ProviderDetailsFormValues,\n ProviderConfigureFormValues,\n SsoProviderFormValues,\n SsoProviderSchema,\n ComponentAction,\n BackButton,\n CreateIdentityProviderRequestContentPrivate,\n} from '@auth0/universal-components-core';\nimport type { LucideIcon } from 'lucide-react';\nimport type React from 'react';\nimport type { UseFormReturn } from 'react-hook-form';\n\nimport type { IdpConfig } from '../../config/config-idp-types';\n\n/**\n * Form display mode for provider configuration\n */\nexport type FormMode = 'create' | 'edit';\n\nexport interface SsoProviderCreateClasses {\n 'SsoProviderCreate-header'?: string;\n 'SsoProviderCreate-wizard'?: string;\n 'ProviderSelect-root'?: string;\n 'ProviderDetails-root'?: string;\n 'ProviderConfigure-root'?: string;\n}\n\nexport interface ProviderSelectProps\n extends SharedComponentProps<ProviderSelectMessages, SsoProviderCreateClasses> {\n isLoading: boolean;\n strategyList: IdpStrategy[];\n onClickStrategy: (strategy: IdpStrategy) => void;\n selectedStrategy?: IdpStrategy | null;\n form?: UseFormReturn<ProviderSelectionFormValues>;\n className?: string;\n}\n\nexport interface ProviderDetailsProps\n extends SharedComponentProps<ProviderDetailsMessages, SsoProviderCreateClasses> {\n initialData?: Partial<ProviderDetailsFormValues>;\n className?: string;\n hideHeader?: boolean;\n mode: 'edit' | 'create';\n onFormDirty?: (isDirty: boolean) => void;\n}\n\nexport interface ProviderConfigureProps\n extends SharedComponentProps<ProviderConfigureMessages, SsoProviderCreateClasses> {\n className?: string;\n isLoading: boolean;\n strategy: IdpStrategy;\n initialData?: Partial<ProviderConfigureFormValues>;\n idpConfig: IdpConfig | null;\n}\n\nexport interface ProviderConfigureFieldsProps\n extends SharedComponentProps<ProviderConfigureFieldsMessages, SsoProviderCreateClasses> {\n strategy: IdpStrategy;\n initialData?: Partial<ProviderConfigureFormValues>;\n className?: string;\n onFormDirty?: (isDirty: boolean) => void;\n idpConfig: IdpConfig | null;\n mode?: FormMode;\n}\n\nexport interface SsoProviderCreateBackButton extends Omit<BackButton, 'onClick'> {\n icon?: LucideIcon;\n onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;\n}\nexport interface SsoProviderCreateProps\n extends SharedComponentProps<\n SsoProviderCreateMessages,\n SsoProviderCreateClasses,\n SsoProviderSchema\n > {\n createAction: ComponentAction<CreateIdentityProviderRequestContentPrivate, IdentityProvider>;\n backButton?: SsoProviderCreateBackButton;\n onPrevious?: (stepId: string, values: Partial<SsoProviderFormValues>) => boolean;\n onNext?: (stepId: string, values: Partial<SsoProviderFormValues>) => boolean;\n}\n\nexport interface UseSsoProviderCreateOptions {\n createAction?: SsoProviderCreateProps['createAction'];\n customMessages?: SsoProviderCreateProps['customMessages'];\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/types/my-organization/idp-management/sso-provider/sso-provider-create-types.ts"
},
{
"path": "src/types/auth-types.ts",
"content": "import type { AuthDetails } from '@auth0/universal-components-core';\nimport type * as React from 'react';\n\nimport type { I18nOptions } from './i18n-types';\nimport type { ThemeSettings } from './theme-types';\n\n/**\n * Props for the Auth0ComponentProvider component.\n */\nexport interface Auth0ComponentProviderProps {\n i18n?: I18nOptions;\n themeSettings?: ThemeSettings;\n authDetails: AuthDetails;\n loader?: React.ReactNode;\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/types/auth-types.ts"
},
{
"path": "src/types/theme-types.ts",
"content": "import type { StylingVariables } from '@auth0/universal-components-core';\nimport type React from 'react';\n\n/**\n * Theme configuration\n * @property {('light'|'dark')} [mode] - Theme mode\n * @property {string} [primaryColor] - Primary color for theming\n */\nexport interface ThemeSettings {\n theme?: 'default' | 'minimal' | 'rounded';\n mode?: 'light' | 'dark';\n variables?: StylingVariables;\n}\n\n/**\n * ThemeInput\n *\n * Optional props passed into the ThemeProvider.\n */\nexport type ThemeInput = {\n theme?: 'default' | 'minimal' | 'rounded';\n mode?: 'light' | 'dark';\n variables?: StylingVariables;\n loader?: React.ReactNode;\n};\n\n/**\n * ThemeContextValue\n *\n * The values made available through the ThemeContext.\n */\nexport type ThemeContextValue = {\n theme?: 'default' | 'minimal' | 'rounded';\n isDarkMode?: boolean;\n variables: StylingVariables;\n loader: React.ReactNode | null;\n};\n",
"type": "registry:file",
"target": "auth0-ui-components/types/theme-types.ts"
},
{
"path": "src/types/i18n-types.ts",
"content": "/**\n * Internationalization configuration for Auth0 components.\n */\nexport interface I18nOptions {\n currentLanguage: string;\n fallbackLanguage?: string;\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/types/i18n-types.ts"
},
{
"path": "src/hoc/with-services.tsx",
"content": "import * as React from 'react';\n\nimport { Spinner } from '../components/ui/spinner';\nimport { useScopeManager } from '../hooks/use-scope-manager';\nimport { useTheme } from '../hooks/use-theme';\n\nexport interface ServiceRequirements {\n myAccountApiScopes?: string;\n myOrganizationApiScopes?: string;\n}\n\nfunction scopesSatisfied(required: string, ensured: string) {\n if (!required) return true;\n const requiredSet = required.split(' ').filter(Boolean);\n const ensuredSet = new Set(ensured.split(' ').filter(Boolean));\n return requiredSet.every((scope) => ensuredSet.has(scope));\n}\n\nfunction normalizeScopes(scopes?: string) {\n return scopes\n ? scopes\n .split(' ')\n .map((s) => s.trim())\n .filter(Boolean)\n .sort()\n .join(' ')\n : '';\n}\n\nexport function withServices<P extends object>(\n WrappedComponent: React.ComponentType<P>,\n requirements: ServiceRequirements = {},\n): React.ComponentType<P> {\n const WithServicesComponent = (props: P) => {\n const { loader } = useTheme();\n const { registerScopes, ensured } = useScopeManager();\n const defaultLoader = (\n <div className=\"fixed inset-0 flex items-center justify-center\">\n <Spinner className=\"h-8 w-8\" />\n </div>\n );\n\n const requiredMe = normalizeScopes(requirements.myAccountApiScopes);\n const requiredOrganization = normalizeScopes(requirements.myOrganizationApiScopes);\n\n const meEnsured = scopesSatisfied(requiredMe, ensured.me);\n const organizationEnsured = scopesSatisfied(requiredOrganization, ensured['my-org']);\n\n React.useEffect(() => {\n if (requirements.myAccountApiScopes) {\n registerScopes('me', requirements.myAccountApiScopes);\n }\n if (requirements.myOrganizationApiScopes) {\n registerScopes('my-org', requirements.myOrganizationApiScopes);\n }\n }, [requirements.myAccountApiScopes, requirements.myOrganizationApiScopes, registerScopes]);\n\n if (\n (requirements.myAccountApiScopes && !meEnsured) ||\n (requirements.myOrganizationApiScopes && !organizationEnsured)\n ) {\n return <>{loader || defaultLoader}</>;\n }\n\n return <WrappedComponent {...props} />;\n };\n\n return WithServicesComponent;\n}\n\nexport function withMyOrganizationService<P extends object>(\n WrappedComponent: React.ComponentType<P>,\n scopes: string,\n): React.ComponentType<P> {\n return withServices(WrappedComponent, { myOrganizationApiScopes: scopes });\n}\n\nexport function withMyAccountService<P extends object>(\n WrappedComponent: React.ComponentType<P>,\n scopes: string,\n): React.ComponentType<P> {\n return withServices(WrappedComponent, { myAccountApiScopes: scopes });\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/hoc/with-services.tsx"
},
{
"path": "src/lib/theme-utils.ts",
"content": "import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/lib/theme-utils.ts"
},
{
"path": "src/assets/icons/entraid-logo.tsx",
"content": "import { EntraIdLogoSvg } from '@auth0/universal-components-core';\nimport React from 'react';\n\nexport interface EntraIdProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n width?: number | string;\n height?: number | string;\n title?: string;\n}\n\n/**\n * EntraIdLogo component renders the EntraId SVG logo.\n *\n * @param props - Props including width, height, title, and standard SVG attributes.\n * @returns A JSX SVG element of the EntraId logo.\n */\nconst EntraIdLogo: React.FC<EntraIdProps> = ({\n width = 17,\n height = 17,\n title = 'EntraID logo',\n className,\n ...props\n}) => {\n return (\n <img\n src={EntraIdLogoSvg}\n alt={title}\n width={width}\n height={height}\n className={className}\n {...props}\n />\n );\n};\n\nexport default React.memo(EntraIdLogo);\n",
"type": "registry:file",
"target": "auth0-ui-components/assets/icons/entraid-logo.tsx"
},
{
"path": "src/assets/icons/google-logo.tsx",
"content": "import { GoogleLogoSvg } from '@auth0/universal-components-core';\nimport React from 'react';\n\nexport interface GoogleLogoProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n width?: number | string;\n height?: number | string;\n title?: string;\n}\n\n/**\n * GoogleLogo component renders the Google \"G\" logo SVG.\n *\n * @param props - Props including width, height, title, and standard SVG attributes.\n * @returns A JSX SVG element of the Google logo.\n */\nconst GoogleLogo: React.FC<GoogleLogoProps> = ({\n width = 48,\n height = 48,\n title = 'Google logo',\n className,\n ...props\n}) => {\n return (\n <img\n src={GoogleLogoSvg}\n alt={title}\n width={width}\n height={height}\n className={className}\n {...props}\n />\n );\n};\n\nexport default React.memo(GoogleLogo);\n",
"type": "registry:file",
"target": "auth0-ui-components/assets/icons/google-logo.tsx"
},
{
"path": "src/assets/icons/microsoft-logo.tsx",
"content": "import { MicrosoftLogoSvg } from '@auth0/universal-components-core';\nimport React from 'react';\n\nexport interface MicrosoftLogoProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n width?: number | string;\n height?: number | string;\n title?: string;\n}\n\n/**\n * MicrosoftLogo component renders the Microsoft logo.\n *\n * @param props - Props including width, height, title, and standard img attributes.\n * @returns A JSX img element of the Microsoft logo.\n */\nconst MicrosoftLogo: React.FC<MicrosoftLogoProps> = ({\n width = 17,\n height = 17,\n title = 'Microsoft logo',\n className,\n ...props\n}) => {\n return (\n <img\n src={MicrosoftLogoSvg}\n alt={title}\n width={width}\n height={height}\n className={className}\n {...props}\n />\n );\n};\n\nexport default React.memo(MicrosoftLogo);\n",
"type": "registry:file",
"target": "auth0-ui-components/assets/icons/microsoft-logo.tsx"
},
{
"path": "src/assets/icons/oidc-logo.tsx",
"content": "import { OidcLogoSvg } from '@auth0/universal-components-core';\nimport React from 'react';\n\nexport interface OidcProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n width?: number | string;\n height?: number | string;\n title?: string;\n}\n\n/**\n * OidcLogo component renders the Oidc logo.\n *\n * @param props - Props including width, height, title, and standard img attributes.\n * @returns A JSX img element of the Oidc logo.\n */\nconst OidcLogo: React.FC<OidcProps> = ({\n width = 17,\n height = 17,\n title = 'Oidc logo',\n className,\n ...props\n}) => {\n return (\n <img\n src={OidcLogoSvg}\n alt={title}\n width={width}\n height={height}\n className={className}\n {...props}\n />\n );\n};\n\nexport default React.memo(OidcLogo);\n",
"type": "registry:file",
"target": "auth0-ui-components/assets/icons/oidc-logo.tsx"
},
{
"path": "src/assets/icons/okta-logo.tsx",
"content": "import { OktaLogoSvg } from '@auth0/universal-components-core';\nimport React from 'react';\n\nexport interface OktaLogoProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n width?: number | string;\n height?: number | string;\n title?: string;\n}\n\n/**\n * OktaLogo component renders the Okta logo.\n *\n * @param props - Props including width, height, title, and standard img attributes.\n * @returns A JSX img element of the Okta logo.\n */\nconst OktaLogo: React.FC<OktaLogoProps> = ({\n width = 17,\n height = 17,\n title = 'Okta logo',\n className,\n ...props\n}) => {\n return (\n <img\n src={OktaLogoSvg}\n alt={title}\n width={width}\n height={height}\n className={className}\n {...props}\n />\n );\n};\n\nexport default React.memo(OktaLogo);\n",
"type": "registry:file",
"target": "auth0-ui-components/assets/icons/okta-logo.tsx"
},
{
"path": "src/assets/icons/pingid-logo.tsx",
"content": "import { PingIdLogoSvg } from '@auth0/universal-components-core';\nimport React from 'react';\n\nexport interface PingIdProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n width?: number | string;\n height?: number | string;\n title?: string;\n}\n\n/**\n * PingIdLogo component renders the PingId logo.\n *\n * @param props - Props including width, height, title, and standard img attributes.\n * @returns A JSX img element of the PingId logo.\n */\nconst PingIdLogo: React.FC<PingIdProps> = ({\n width = 17,\n height = 17,\n title = 'PingId logo',\n className,\n ...props\n}) => {\n return (\n <img\n src={PingIdLogoSvg}\n alt={title}\n width={width}\n height={height}\n className={className}\n {...props}\n />\n );\n};\n\nexport default React.memo(PingIdLogo);\n",
"type": "registry:file",
"target": "auth0-ui-components/assets/icons/pingid-logo.tsx"
},
{
"path": "src/assets/icons/sampl-logo.tsx",
"content": "import { SamlpLogoSvg } from '@auth0/universal-components-core';\nimport React from 'react';\n\nexport interface SamlpProps extends React.ImgHTMLAttributes<HTMLImageElement> {\n width?: number | string;\n height?: number | string;\n title?: string;\n}\n\n/**\n * SamlpLogo component renders the Samlp logo.\n *\n * @param props - Props including width, height, title, and standard img attributes.\n * @returns A JSX img element of the Samlp logo.\n */\nconst SamlpLogo: React.FC<SamlpProps> = ({\n width = 17,\n height = 17,\n title = 'Samlp logo',\n className,\n ...props\n}) => {\n return (\n <img\n src={SamlpLogoSvg}\n alt={title}\n width={width}\n height={height}\n className={className}\n {...props}\n />\n );\n};\n\nexport default React.memo(SamlpLogo);\n",
"type": "registry:file",
"target": "auth0-ui-components/assets/icons/sampl-logo.tsx"
},
{
"path": "src/styles/globals.css",
"content": "@import 'tailwindcss';\n\n@import './font-sizes.css';\n\n@import './themes/default.css';\n@import './themes/minimal.css';\n@import './themes/rounded.css';\n\n:root {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n@layer base {\n body {\n @apply antialiased;\n font-feature-settings:\n 'rlig' 1,\n 'calt' 1;\n }\n\n .color-scheme-transitioning *,\n .color-scheme-transitioning *::before,\n .color-scheme-transitioning *::after {\n transition: var(--color-scheme-transition) !important;\n transition-delay: 0ms !important;\n }\n}\n\n:root {\n * {\n scrollbar-width: thin;\n scrollbar-color: hsl(var(--border)) transparent;\n }\n\n ::-webkit-scrollbar {\n width: 6px;\n }\n\n ::-webkit-scrollbar-thumb {\n background: hsl(var(--border));\n border-radius: 6px;\n }\n\n ::-webkit-scrollbar-track {\n background: transparent;\n }\n}\n\n@theme inline {\n /**\n * STANDARD SHADCN VARIABLES (with auth0 fallbacks)\n * Map shadcn standard variable names defined by the user to auth0 ones\n */\n --color-background: var(--background, var(--color-neutral-min));\n --color-foreground: var(--foreground, var(--color-neutral-12));\n --color-card: var(--card, var(--color-neutral-min));\n --color-card-foreground: var(--card-foreground, var(--color-neutral-max));\n --color-primary: var(--primary, var(--color-carbon-9));\n --color-primary-foreground: var(--primary-foreground, var(--color-neutral-min));\n --color-secondary: var(--secondary, var(--color-neutral-3));\n --color-secondary-foreground: var(--secondary-foreground, var(--color-neutral-1));\n --color-accent: var(--accent, var(--color-neutral-2));\n --color-accent-foreground: var(--accent-foreground, var(--color-neutral-12));\n --color-muted: var(--muted, var(--color-neutral-2));\n --color-muted-foreground: var(--muted-foreground, var(--color-neutral-11));\n --color-destructive: var(--destructive, var(--color-red-3));\n --color-destructive-foreground: var(--destructive-foreground, var(--color-red-9));\n --color-popover: var(--popover, var(--color-neutral-1));\n --color-popover-foreground: var(--popover-foreground, var(--color-neutral-12));\n --color-input: var(--input, var(--color-neutral-1));\n --color-border: var(--border, var(--color-neutral-6));\n --color-ring: var(--ring, hsla(var(--color-neutral-7), 0.2));\n\n /**\n * CUSTOM AUTH0 VARIABLES (no shadcn equivalents)\n * These are auth0-specific and don't map to standard shadcn variables\n */\n\n /* Page background */\n --color-page: var(--color-neutral-2);\n\n /* Status colors */\n --color-info: var(--color-blue-3);\n --color-info-foreground: var(--color-blue-9);\n --color-success: var(--color-green-3);\n --color-success-foreground: var(--color-green-9);\n --color-warning: var(--color-yellow-3);\n --color-warning-foreground: var(--color-yellow-11);\n\n /* Extended semantic colors */\n --color-destructive-border: var(--color-red-10);\n --color-popover-border: var(--color-neutral-6);\n --color-input-foreground: var(--color-neutral-12);\n --color-input-muted: var(--color-neutral-2);\n\n /* Shadows */\n --shadow-bevel-xs: var(--shadow-bevel-xs);\n --shadow-bevel-sm: var(--shadow-bevel-sm);\n --shadow-bevel-md: var(--shadow-bevel-md);\n --shadow-bevel-lg: var(--shadow-bevel-md);\n --shadow-bevel-xl: var(--shadow-bevel-xl);\n --shadow-bevel-2xl: var(--shadow-bevel-2xl);\n\n --shadow-button-resting: var(--shadow-button-resting);\n --shadow-button-hover: var(--shadow-button-hover);\n --shadow-button-focus: var(--shadow-button-hover);\n\n --shadow-button-destructive-resting: var(--shadow-button-destructive-resting);\n --shadow-button-destructive-hover: var(--shadow-button-destructive-hover);\n --shadow-button-destructive-focus: var(--shadow-button-destructive-focus);\n\n --shadow-button-outlined-resting: var(--shadow-button-outlined-resting);\n --shadow-button-outlined-hover: var(--shadow-button-outlined-resting);\n --shadow-button-outlined-focus: var(--shadow-button-outlined-resting);\n\n --shadow-input-resting: var(--shadow-input-resting);\n --shadow-input-hover: var(--shadow-input-hover);\n --shadow-input-focus: var(--shadow-input-focus);\n --shadow-input-destructive-resting: var(--shadow-input-destructive-resting);\n --shadow-input-destructive-hover: var(--shadow-input-destructive-hover);\n --shadow-input-destructive-focus: var(--shadow-input-destructive-focus);\n\n --shadow-checkbox-resting: var(--shadow-checkbox-resting);\n --shadow-checkbox-hover: var(--shadow-checkbox-hover);\n\n --shadow-switch-resting: var(--shadow-switch-resting);\n --shadow-switch-hover: var(--shadow-switch-resting);\n --shadow-switch-focus: var(--shadow-switch-focus);\n --shadow-switch-thumb: var(--shadow-switch-thumb);\n --shadow-switch-thumb-dark: var(--shadow-switch-thumb-dark);\n\n /* Border radius */\n --radius-xs: var(--radius-xs);\n --radius-sm: var(--radius-sm);\n --radius-md: var(--radius-md);\n --radius-lg: var(--radius-lg);\n --radius-xl: var(--radius-xl);\n --radius-2xl: var(--radius-2xl);\n --radius-3xl: var(--radius-3xl);\n --radius-4xl: var(--radius-4xl);\n --radius-5xl: var(--radius-5xl);\n --radius-6xl: var(--radius-6xl);\n --radius-7xl: var(--radius-7xl);\n --radius-8xl: var(--radius-8xl);\n --radius-9xl: var(--radius-9xl);\n\n /* Defined in font-sizes.css */\n --font-size-page-header: var(--font-size-page-header);\n --font-size-page-description: var(--font-size-page-description);\n --font-size-heading: var(--font-size-heading);\n --font-size-title: var(--font-size-title);\n --font-size-subtitle: var(--font-size-subtitle);\n --font-size-body: var(--font-size-body);\n --font-size-paragraph: var(--font-size-paragraph);\n --font-size-label: var(--font-size-label);\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/styles/globals.css"
},
{
"path": "src/styles/font-sizes.css",
"content": ":root {\n --font-size-page-header: 2.25rem; /* text-4xl (For main page headers/titles) */\n --font-size-page-description: 0.875rem; /* text-sm (For page descriptions/subtitles) */\n --font-size-heading: 1.5rem; /* text-2xl */\n --font-size-title: 1.25rem; /* text-xl */\n --font-size-subtitle: 1.125rem; /* text-lg */\n --font-size-body: 1rem; /* text-base (For main body text size) */\n --font-size-paragraph: 0.875rem; /* text-sm (For general smaller paragraphs/details) */\n --font-size-label: 0.875rem; /* text-sm (Specifically for labels like FieldLabel) */\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/styles/font-sizes.css"
},
{
"path": "src/styles/dark.css",
"content": ".dark {\n --color-white: oklch(100% 0 0);\n --color-black: oklch(0% 0 0);\n\n --color-neutral-min: oklch(0% 0 0);\n --color-neutral-max: oklch(100% 0 0);\n\n --color-neutral-1: oklch(17.76% 0 0);\n --color-neutral-2: oklch(21.34% 0 0);\n --color-neutral-3: oklch(25.2% 0 0);\n --color-neutral-4: oklch(28.5% 0 0);\n --color-neutral-5: oklch(31.32% 0 0);\n --color-neutral-6: oklch(34.85% 0 0);\n --color-neutral-7: oklch(40.17% 0 0);\n --color-neutral-8: oklch(48.91% 0 0);\n --color-neutral-9: oklch(53.82% 0 0);\n --color-neutral-10: oklch(58.29% 0 0);\n --color-neutral-11: oklch(76.99% 0 0);\n --color-neutral-12: oklch(94.91% 0 0);\n\n --color-carbon-1: oklch(21.42% 0.0025 67.69);\n --color-carbon-2: oklch(24.42% 0.0024 67.71);\n --color-carbon-3: oklch(27.72% 0.0039 84.58);\n --color-carbon-4: oklch(30.25% 0.0046 67.65);\n --color-carbon-5: oklch(32.86% 0.007 95.27);\n --color-carbon-6: oklch(36.1% 0.0058 78.26);\n --color-carbon-7: oklch(40.97% 0.0071 84.59);\n --color-carbon-8: oklch(49.35% 0.0054 78.28);\n --color-carbon-9: oklch(54.48% 0.0062 95.17);\n --color-carbon-10: oklch(49.7% 0.0053 78.28);\n --color-carbon-11: oklch(77.04% 0.0061 84.57);\n --color-carbon-12: oklch(94.65% 0.0058 84.57);\n\n --color-blue-1: oklch(21.49% 0.0269 267.91);\n --color-blue-2: oklch(22.6% 0.0341 270.96);\n --color-blue-3: oklch(28.32% 0.0764 269.7);\n --color-blue-4: oklch(32.6% 0.1045 269.69);\n --color-blue-5: oklch(36.47% 0.1171 269.75);\n --color-blue-6: oklch(40.57% 0.1233 269.28);\n --color-blue-7: oklch(45.2% 0.1334 269.49);\n --color-blue-8: oklch(50.37% 0.1522 269.22);\n --color-blue-9: oklch(53.13% 0.2117 269.5);\n --color-blue-10: oklch(48.35% 0.1516 269.24);\n --color-blue-11: oklch(77.13% 0.1158 267.4);\n --color-blue-12: oklch(91.01% 0.0431 268.21);\n\n --color-indigo-1: oklch(21.21% 0.0351 288.11);\n --color-indigo-2: oklch(22.69% 0.0402 287.09);\n --color-indigo-3: oklch(28.15% 0.0877 288.67);\n --color-indigo-4: oklch(31.89% 0.1235 288.38);\n --color-indigo-5: oklch(35.27% 0.1311 287.97);\n --color-indigo-6: oklch(39.12% 0.1355 288.23);\n --color-indigo-7: oklch(44.48% 0.1476 288.08);\n --color-indigo-8: oklch(51.52% 0.1734 288.29);\n --color-indigo-9: oklch(55.63% 0.2368 288.08);\n --color-indigo-10: oklch(51.1% 0.1735 287.75);\n --color-indigo-11: oklch(77.21% 0.1244 289.4);\n --color-indigo-12: oklch(90.77% 0.0476 289.35);\n\n --color-green-1: oklch(17.75% 0.0149 153.63);\n --color-green-2: oklch(21.06% 0.019 151.28);\n --color-green-3: oklch(27.18% 0.0438 151.94);\n --color-green-4: oklch(31.66% 0.0629 152.81);\n --color-green-5: oklch(36.4% 0.073 152.83);\n --color-green-6: oklch(41.39% 0.082 152.61);\n --color-green-7: oklch(46.81% 0.093 152.52);\n --color-green-8: oklch(52.84% 0.1092 152.24);\n --color-green-9: oklch(59.48% 0.1496 152.41);\n --color-green-10: oklch(55.19% 0.1085 152.38);\n --color-green-11: oklch(77.88% 0.1495 152.37);\n --color-green-12: oklch(90.49% 0.0926 152.37);\n\n --color-red-1: oklch(17.71% 0.0174 25.39);\n --color-red-2: oklch(20.36% 0.0277 31.18);\n --color-red-3: oklch(24.99% 0.0801 30.49);\n --color-red-4: oklch(28.91% 0.1186 29.23);\n --color-red-5: oklch(33.17% 0.1327 30.08);\n --color-red-6: oklch(38.19% 0.1379 30.13);\n --color-red-7: oklch(45.04% 0.1499 30.04);\n --color-red-8: oklch(54.3% 0.1822 30);\n --color-red-9: oklch(55.69% 0.1824 30.14);\n --color-red-10: oklch(51.17% 0.1823 30.25);\n --color-red-11: oklch(76.81% 0.1378 30.76);\n --color-red-12: oklch(89.34% 0.0563 31.82);\n\n --color-orange-1: oklch(17.86% 0.0094 43);\n --color-orange-2: oklch(20.74% 0.0138 51.4);\n --color-orange-3: oklch(25.53% 0.0384 48.1);\n --color-orange-4: oklch(29.31% 0.0658 46.26);\n --color-orange-5: oklch(33.42% 0.0725 46.84);\n --color-orange-6: oklch(38.44% 0.0734 46.75);\n --color-orange-7: oklch(45.06% 0.0809 45.76);\n --color-orange-8: oklch(53.96% 0.0992 47.07);\n --color-orange-9: oklch(67.09% 0.1589 46.43);\n --color-orange-10: oklch(63.3% 0.1593 46.45);\n --color-orange-11: oklch(79.01% 0.1315 47.24);\n --color-orange-12: oklch(91.62% 0.0401 47.46);\n\n --color-yellow-1: oklch(17.78% 0.0122 91.81);\n --color-yellow-2: oklch(20.95% 0.0174 91.81);\n --color-yellow-3: oklch(25.74% 0.0441 95.12);\n --color-yellow-4: oklch(29.68% 0.0608 94.08);\n --color-yellow-5: oklch(33.71% 0.0691 93.95);\n --color-yellow-6: oklch(38.5% 0.0781 96.28);\n --color-yellow-7: oklch(45.34% 0.0819 97.18);\n --color-yellow-8: oklch(53.62% 0.0964 96.34);\n --color-yellow-9: oklch(84.96% 0.1743 96.46);\n --color-yellow-10: oklch(81.98% 0.1686 95.87);\n --color-yellow-11: oklch(87.68% 0.1743 96.48);\n --color-yellow-12: oklch(93.7% 0.0732 96.57);\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/styles/dark.css"
},
{
"path": "src/styles/light.css",
"content": ":root {\n --color-white: oklch(100% 0 0);\n --color-black: oklch(0% 0 0);\n\n --color-neutral-min: oklch(100% 0 0);\n --color-neutral-max: oklch(0% 0 0);\n\n --color-neutral-1: oklch(99.11% 0 0);\n --color-neutral-2: oklch(98.21% 0 0);\n --color-neutral-3: oklch(95.51% 0 0);\n --color-neutral-4: oklch(93.1% 0 0);\n --color-neutral-5: oklch(90.97% 0 0);\n --color-neutral-6: oklch(88.53% 0 0);\n --color-neutral-7: oklch(85.14% 0 0);\n --color-neutral-8: oklch(79.21% 0 0);\n --color-neutral-9: oklch(64.01% 0 0);\n --color-neutral-10: oklch(60.66% 0 0);\n --color-neutral-11: oklch(49.97% 0 0);\n --color-neutral-12: oklch(23.93% 0 0);\n\n --color-carbon-1: oklch(99.38% 0.0013 106.42);\n --color-carbon-2: oklch(98.26% 0.0017 67.8);\n --color-carbon-3: oklch(95.51% 0.0041 91.45);\n --color-carbon-4: oklch(93.14% 0.0058 84.57);\n --color-carbon-5: oklch(90.76% 0.0075 80.72);\n --color-carbon-6: oklch(88.06% 0.0093 78.28);\n --color-carbon-7: oklch(84.62% 0.0118 84.58);\n --color-carbon-8: oklch(78.36% 0.012 84.58);\n --color-carbon-9: oklch(26.93% 0.0078 84.59);\n --color-carbon-10: oklch(34.91% 0.0074 84.59);\n --color-carbon-11: oklch(50.02% 0.0115 87.52);\n --color-carbon-12: oklch(26.1% 0.0079 84.59);\n\n --color-blue-1: oklch(96.77% 0.0027 286.35);\n --color-blue-2: oklch(95.53% 0.0083 271.33);\n --color-blue-3: oklch(93.1% 0.0184 269.08);\n --color-blue-4: oklch(90.41% 0.0372 268.89);\n --color-blue-5: oklch(86.93% 0.0576 270);\n --color-blue-6: oklch(82.79% 0.079 269.55);\n --color-blue-7: oklch(77% 0.0956 268.87);\n --color-blue-8: oklch(69.15% 0.126 269.7);\n --color-blue-9: oklch(53.13% 0.2117 269.5);\n --color-blue-10: oklch(48.45% 0.1918 269.57);\n --color-blue-11: oklch(47.22% 0.1921 269.55);\n --color-blue-12: oklch(31.36% 0.0956 269.13);\n\n --color-indigo-1: oklch(96.58% 0.0041 301.42);\n --color-indigo-2: oklch(95.47% 0.012 286.17);\n --color-indigo-3: oklch(93.33% 0.0242 285.92);\n --color-indigo-4: oklch(90.16% 0.0504 287.82);\n --color-indigo-5: oklch(90.16% 0.0504 287.82);\n --color-indigo-6: oklch(82.63% 0.0921 288.37);\n --color-indigo-7: oklch(77.02% 0.1189 287.63);\n --color-indigo-8: oklch(69.06% 0.1566 287.89);\n --color-indigo-9: oklch(55.63% 0.2368 288.08);\n --color-indigo-10: oklch(50.99% 0.2119 287.99);\n --color-indigo-11: oklch(47.02% 0.2114 288.14);\n --color-indigo-12: oklch(31.4% 0.1289 288.26);\n\n --color-green-1: oklch(99.32% 0.0058 153.78);\n --color-green-2: oklch(98.14% 0.0099 155.1);\n --color-green-3: oklch(96% 0.0248 152.88);\n --color-green-4: oklch(93.3% 0.039 153.49);\n --color-green-5: oklch(90.13% 0.0566 152.99);\n --color-green-6: oklch(85.72% 0.0751 152.95);\n --color-green-7: oklch(79.82% 0.0995 152.34);\n --color-green-8: oklch(71.73% 0.1375 152.09);\n --color-green-9: oklch(59.48% 0.1496 152.41);\n --color-green-10: oklch(55.05% 0.1399 152.51);\n --color-green-11: oklch(52.83% 0.1391 151.98);\n --color-green-12: oklch(32.7% 0.0573 152.54);\n\n --color-red-1: oklch(99.34% 0.0032 17.21);\n --color-red-2: oklch(98.35% 0.0066 28.83);\n --color-red-3: oklch(95.55% 0.0193 33.36);\n --color-red-4: oklch(92.39% 0.0391 31.56);\n --color-red-5: oklch(89.37% 0.056 30.52);\n --color-red-6: oklch(85.5% 0.0701 30.6);\n --color-red-7: oklch(80.46% 0.0849 29.91);\n --color-red-8: oklch(74.16% 0.1072 29.84);\n --color-red-9: oklch(55.69% 0.1824 30.14);\n --color-red-10: oklch(51.17% 0.1823 30.25);\n --color-red-11: oklch(56.26% 0.1824 30.09);\n --color-red-12: oklch(34.39% 0.0841 30.19);\n\n --color-orange-1: oklch(99.25% 0.003 44.27);\n --color-orange-2: oklch(97.9% 0.0111 45.72);\n --color-orange-3: oklch(95.53% 0.0254 52.23);\n --color-orange-4: oklch(91.14% 0.0525 53.02);\n --color-orange-5: oklch(88.02% 0.0723 52.29);\n --color-orange-6: oklch(85.53% 0.0857 47.69);\n --color-orange-7: oklch(80.43% 0.0914 46.16);\n --color-orange-8: oklch(74.44% 0.1083 45.72);\n --color-orange-9: oklch(67.09% 0.1589 46.43);\n --color-orange-10: oklch(63.27% 0.1618 46.35);\n --color-orange-11: oklch(58.9% 0.1549 46.78);\n --color-orange-12: oklch(34.87% 0.0582 46.18);\n\n --color-yellow-1: oklch(99.4% 0.0041 91.45);\n --color-yellow-2: oklch(98.64% 0.024 96.56);\n --color-yellow-3: oklch(96.63% 0.0746 100.25);\n --color-yellow-4: oklch(94.59% 0.1098 99.21);\n --color-yellow-5: oklch(92.1% 0.1367 96.69);\n --color-yellow-6: oklch(88.11% 0.129 96.8);\n --color-yellow-7: oklch(83.15% 0.1212 96.92);\n --color-yellow-8: oklch(76.19% 0.138 96.64);\n --color-yellow-9: oklch(88.88% 0.1827 95.76);\n --color-yellow-10: oklch(85.87% 0.1743 96.46);\n --color-yellow-11: oklch(57.39% 0.1176 93.46);\n --color-yellow-12: oklch(35.58% 0.0457 96.16);\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/styles/light.css"
},
{
"path": "src/styles/themes/default.css",
"content": "@import '../light.css';\n@import '../dark.css';\n\n@custom-variant theme-default {\n &:where([data-theme='default'] *) {\n @slot;\n }\n}\n\n@layer base {\n [data-theme='default'] {\n /**\n * STANDARD SHADCN VARIABLES with user fallbacks\n * Users can override by defining --primary, --background, etc.\n */\n --color-page: var(--color-neutral-2);\n --color-background: var(--background, var(--color-neutral-min));\n --color-foreground: var(--foreground, var(--color-neutral-12));\n\n --color-card: var(--card, var(--color-neutral-min));\n --color-card-foreground: var(--card-foreground, var(--color-neutral-max));\n\n --color-primary: var(--primary, var(--color-carbon-12));\n --color-primary-foreground: var(--primary-foreground, var(--color-neutral-min));\n\n --color-secondary: var(--secondary, var(--color-neutral-3));\n --color-secondary-foreground: var(--secondary-foreground, var(--color-neutral-1));\n\n --color-accent: var(--accent, var(--color-neutral-9));\n --color-accent-foreground: var(--accent-foreground, var(--color-neutral-12));\n\n --color-muted: var(--muted, var(--color-neutral-3));\n --color-muted-foreground: var(--muted-foreground, var(--color-neutral-10));\n\n --color-border: var(--border, var(--color-neutral-6));\n --color-ring: var(--ring, oklch(from var(--color-neutral-7) l c h / 50%));\n\n --color-info: var(--color-blue-3);\n --color-info-foreground: var(--color-blue-11);\n --color-success: var(--color-green-3);\n --color-success-foreground: var(--color-green-11);\n --color-warning: var(--color-yellow-3);\n --color-warning-foreground: var(--color-yellow-11);\n\n --color-destructive: var(--destructive, var(--color-red-4));\n --color-destructive-foreground: var(--destructive-foreground, var(--color-red-11));\n --color-destructive-border: var(--color-red-10);\n\n --color-popover: var(--popover, var(--color-neutral-min));\n --color-popover-foreground: var(--popover-foreground, var(--color-neutral-12));\n\n --color-input: var(--input, var(--color-neutral-min));\n --color-input-foreground: var(--color-neutral-12);\n --color-input-muted: var(--color-neutral-3);\n\n --shadow-bevel-xs:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 2px -1px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 1px 1px -0.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px -1.5px 1.5px -1.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px 3px 3px -1.5px oklch(from oklch(100% 0 0) l c h / 10%);\n --shadow-bevel-sm:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 4px 4px -2px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 2px 2px -1px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 1px 1px -0.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px -1.5px 1.5px -1.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px 3px 3px -1.5px oklch(from oklch(100% 0 0) l c h / 10%);\n --shadow-bevel-md:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 6px 6px -3px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 4px 4px -1px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 2px 2px -1px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 1px 1px -0.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px -1.5px 1.5px -1.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px 3px 3px -1.5px oklch(from oklch(100% 0 0) l c h / 10%);\n --shadow-bevel-lg:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 12px 12px -6px oklch(from oklch(0% 0 0) l c h / 10%),\n 0px 6px 6px -1.5px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 4px 4px 0px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 2px 2px -1px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 1px 1px -0.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px -1.5px 1.5px -1.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px 3px 3px -1.5px oklch(from oklch(100% 0 0) l c h / 10%);\n --shadow-bevel-xl:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 24px 24px -22px oklch(from oklch(0% 0 0) l c h / 10%),\n 0px 12px 12px -8px oklch(from oklch(0% 0 0) l c h / 10%),\n 0px 6px 6px -3px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 4px 4px 2px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 2px 2px -1px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 1px 1px -0.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px -1.5px 1.5px -1.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px 3px 3px -1.5px oklch(from oklch(100% 0 0) l c h / 10%);\n --shadow-bevel-2xl:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 40px 40px -28px oklch(from oklch(0% 0 0) l c h / 10%),\n 0px 24px 24px -28px oklch(from oklch(0% 0 0) l c h / 10%),\n 0px 12px 12px -8px oklch(from oklch(0% 0 0) l c h / 10%),\n 0px 6px 6px -3px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 4px 4px 2px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 2px 2px -1px oklch(from oklch(0% 0 0) l c h / 5%),\n 0px 1px 1px -0.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px -1.5px 1.5px -1.5px oklch(from oklch(0% 0 0) l c h / 5%),\n inset 0px 3px 3px -1.5px oklch(from oklch(100% 0 0) l c h / 10%);\n\n --shadow-button-resting:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 4px 8px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 8px 12px -8px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0px -2px 2px -1px oklch(from var(--color-neutral-max) l c h / 50%),\n inset 0px 2px 2px -1px oklch(from var(--color-neutral-min) l c h / 20%);\n --shadow-button-hover:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 15%),\n 0px 2px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 4px 8px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 8px 12px -8px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0px -2px 2px -1px oklch(from var(--color-neutral-max) l c h / 50%),\n inset 0px 2px 2px -1px oklch(from var(--color-neutral-min) l c h / 20%);\n\n --shadow-button-destructive-resting:\n 0px 0px 0px 1px oklch(from var(--color-destructive-border) l c h / 5%),\n 0px 2px 2px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 1px 1px -0.5px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 4px 8px -2px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 8px 12px -8px oklch(from var(--color-destructive-border) l c h / 10%),\n inset 0px -2px 2px -1px oklch(from var(--color-destructive-border) l c h / 20%),\n inset 0px 4px 2px -2px oklch(from var(--color-neutral-min) l c h / 15%);\n --shadow-button-destructive-hover:\n 0px 0px 0px 1px oklch(from var(--color-destructive-border) l c h / 15%),\n 0px 2px 2px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 1px 1px -0.5px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 4px 8px -2px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 8px 12px -8px oklch(from var(--color-destructive-border) l c h / 10%),\n inset 0px -2px 2px -1px oklch(from var(--color-destructive-border) l c h / 20%),\n inset 0px 4px 2px -2px oklch(from var(--color-neutral-min) l c h / 15%);\n\n --shadow-button-outlined-resting:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 4px 8px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0px -2px 2px -1px oklch(from var(--color-neutral-max) l c h / 20%),\n inset 0px 4px 2px -2px oklch(from var(--color-neutral-min) l c h / 15%);\n --shadow-button-outlined-hover:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 15%),\n 0px 2px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 4px 8px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0px -2px 2px -1px oklch(from var(--color-neutral-max) l c h / 20%),\n inset 0px 4px 2px -2px oklch(from var(--color-neutral-min) l c h / 15%);\n\n --shadow-input-resting:\n 0 0 0 1px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0 -1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 0.5px 0px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 1px 0 -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 4px 8px -8px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 8px 12px -12px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-input-hover:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 20%),\n inset 0 -1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 0.5px 0px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 1px 0 -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 4px 8px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 8px 12px -12px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-input-destructive-resting:\n 0 0 0 1px oklch(from var(--color-destructive-border) l c h / 15%),\n inset 0 -1px 2px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 0.5px 0px -0.5px oklch(from var(--color-destructive-border) l c h / 10%),\n 0 1px 0 -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 1px 2px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-destructive-border) l c h / 10%),\n 0 4px 8px -8px oklch(from var(--color-destructive-border) l c h / 10%),\n 0 8px 12px -12px oklch(from var(--color-destructive-border) l c h / 10%);\n --shadow-input-destructive-hover:\n 0px 0px 0px 1px oklch(from var(--color-destructive-border) l c h / 25%),\n inset 0 -1px 2px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 0.5px 0px -0.5px oklch(from var(--color-destructive-border) l c h / 10%),\n 0 1px 0 -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 1px 2px -1px oklch(from var(--color-destructive-border) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-destructive-border) l c h / 10%),\n 0 4px 8px -2px oklch(from var(--color-destructive-border) l c h / 10%),\n 0 8px 12px -12px oklch(from var(--color-destructive-border) l c h / 10%);\n\n --shadow-checkbox-resting:\n 0px 0.5px 0px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 1px 0 -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 4px 6px -8px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0px -1px 2px -1px oklch(from var(--color-neutral-max) l c h / 20%),\n inset 0px 2px 1px -1px oklch(from var(--color-neutral-min) l c h / 50%);\n --shadow-checkbox-hover:\n 0px 0.5px 0px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 1px 0 -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 4px 6px -8px oklch(from var(--color-neutral-max) l c h / 10%),\n 0 8px 12px -8px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0px -1px 2px -1px oklch(from var(--color-neutral-max) l c h / 20%),\n inset 0px 2px 1px -1px oklch(from var(--color-neutral-min) l c h / 50%);\n\n --shadow-switch-resting:\n 0 0 0 1px oklch(from var(--color-neutral-max) l c h / 5%),\n inset 0px 0.5px 1px 0px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-switch-hover:\n 0 0 0 1px oklch(from var(--color-neutral-max) l c h / 10%),\n inset 0px 0.5px 1px 0.5px oklch(from var(--color-neutral-max) l c h / 10%);\n\n --shadow-switch-thumb:\n 4px 8px 12px -6px oklch(from var(--color-neutral-max) l c h / 10%),\n 2px 2px 8px -4px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 0px 0px 0.25px oklch(from var(--color-neutral-max) l c h / 10%),\n 0.5px 0.5px 1px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 1px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 1px 1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 2px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 25%),\n inset -2px -3px 2px -2px oklch(from var(--color-neutral-min) l c h / 100%),\n inset 0.25px 0.25px 0.5px oklch(from var(--color-neutral-min) l c h / 75%),\n inset -4px -4px 16px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n inset 8px 6px 8px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n inset 0px -0.5px 2px 0.5px oklch(from var(--color-neutral-max) l c h / 10%);\n\n --shadow-switch-thumb-dark:\n 4px 8px 12px -6px oklch(from var(--color-neutral-max) l c h / 10%),\n 2px 2px 8px -4px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 0px 0px 0.25px oklch(from var(--color-neutral-max) l c h / 10%),\n 0.5px 0.5px 1px -0.5px oklch(from var(--color-neutral-max) l c h / 10%),\n 1px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 1px 1px 2px -1px oklch(from var(--color-neutral-max) l c h / 10%),\n 2px 2px 4px -2px oklch(from var(--color-neutral-max) l c h / 25%),\n inset -2px -3px 2px -2px oklch(from var(--color-neutral-min) l c h / 10%),\n inset 0.25px 0.25px 0.5px oklch(from var(--color-neutral-min) l c h / 25%),\n inset -4px -4px 16px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n inset 8px 6px 8px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n inset 0px -0.5px 2px 0.5px oklch(from var(--color-neutral-max) l c h / 10%);\n\n --radius-xs: 2px;\n --radius-sm: 4px;\n --radius-md: 6px;\n --radius-lg: 10px;\n --radius-xl: 12px;\n --radius-2xl: 14px;\n --radius-3xl: 16px;\n --radius-4xl: 20px;\n --radius-5xl: 24px;\n --radius-6xl: 32px;\n --radius-7xl: 40px;\n --radius-8xl: 48px;\n --radius-9xl: 56px;\n }\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/styles/themes/default.css"
},
{
"path": "src/styles/themes/minimal.css",
"content": "@import '../light.css';\n@import '../dark.css';\n\n@custom-variant theme-minimal {\n &:where([data-theme='minimal'] *) {\n @slot;\n }\n}\n\n@layer base {\n [data-theme='minimal'] {\n /**\n * STANDARD SHADCN VARIABLES with user fallbacks\n * Users can override by defining --primary, --background, etc.\n */\n --color-page: var(--color-neutral-2);\n --color-background: var(--background, var(--color-neutral-min));\n --color-foreground: var(--foreground, var(--color-neutral-12));\n\n --color-card: var(--card, var(--color-neutral-min));\n --color-card-foreground: var(--card-foreground, var(--color-neutral-max));\n\n --color-primary: var(--primary, var(--color-carbon-9));\n --color-primary-foreground: var(--primary-foreground, var(--color-neutral-min));\n\n --color-secondary: var(--secondary, var(--color-neutral-3));\n --color-secondary-foreground: var(--secondary-foreground, var(--color-neutral-1));\n\n --color-accent: var(--accent, var(--color-neutral-9));\n --color-accent-foreground: var(--accent-foreground, var(--color-neutral-12));\n\n --color-muted: var(--muted, var(--color-neutral-3));\n --color-muted-foreground: var(--muted-foreground, var(--color-neutral-10));\n\n --color-border: var(--border, var(--color-neutral-6));\n --color-ring: var(--ring, oklch(from var(--color-neutral-7) l c h / 50%));\n\n --color-info: var(--color-blue-3);\n --color-info-foreground: var(--color-blue-9);\n --color-success: var(--color-green-3);\n --color-success-foreground: var(--color-green-9);\n --color-warning: var(--color-yellow-3);\n --color-warning-foreground: var(--color-yellow-11);\n\n --color-destructive: var(--destructive, var(--color-red-3));\n --color-destructive-foreground: var(--destructive-foreground, var(--color-red-9));\n --color-destructive-border: var(--color-red-10);\n\n --color-popover: var(--popover, var(--color-neutral-1));\n --color-popover-foreground: var(--popover-foreground, var(--color-neutral-12));\n\n --color-input: var(--input, var(--color-neutral-3));\n --color-input-foreground: var(--color-neutral-12);\n --color-input-muted: var(--color-neutral-3);\n\n --shadow-bevel-xs:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%);\n --shadow-bevel-sm:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%);\n --shadow-bevel-md:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%);\n --shadow-bevel-lg:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 6px 3px -6px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-bevel-xl:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 6px 3px -6px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 12px 6px -12px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-bevel-2xl:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 6px 3px -6px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 12px 6px -12px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 24px 12px -24px oklch(from var(--color-neutral-max) l c h / 10%);\n\n --shadow-button-resting: none;\n --shadow-button-hover: none;\n\n --shadow-button-destructive-resting: none;\n --shadow-button-destructive-hover: none;\n\n --shadow-button-outlined-resting: none;\n --shadow-button-outlined-hover: none;\n\n --shadow-input-resting: none;\n --shadow-input-hover: none;\n --shadow-input-destructive-resting: none;\n --shadow-input-destructive-hover: none;\n --shadow-input-destructive-focus: none;\n\n --shadow-checkbox-resting: none;\n --shadow-checkbox-hover: none;\n\n --shadow-switch-resting: none;\n --shadow-switch-hover: none;\n --shadow-switch-focus: none;\n --shadow-switch-thumb: none;\n\n --radius-xs: 4px;\n --radius-sm: 6px;\n --radius-md: 8px;\n --radius-lg: 10px;\n --radius-xl: 12px;\n --radius-2xl: 14px;\n --radius-3xl: 16px;\n --radius-4xl: 20px;\n --radius-5xl: 24px;\n --radius-6xl: 32px;\n --radius-7xl: 40px;\n --radius-8xl: 48px;\n --radius-9xl: 56px;\n }\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/styles/themes/minimal.css"
},
{
"path": "src/styles/themes/rounded.css",
"content": "@import '../light.css';\n@import '../dark.css';\n\n@custom-variant theme-rounded {\n &:where([data-theme='rounded'] *) {\n @slot;\n }\n}\n\n@layer base {\n [data-theme='rounded'] {\n /**\n * STANDARD SHADCN VARIABLES with user fallbacks\n * Users can override by defining --primary, --background, etc.\n */\n --color-page: var(--color-neutral-2);\n --color-background: var(--background, var(--color-neutral-1));\n --color-foreground: var(--foreground, var(--color-neutral-12));\n\n --color-card: var(--card, var(--color-neutral-min));\n --color-card-foreground: var(--card-foreground, var(--color-neutral-max));\n\n --color-primary: var(--primary, var(--color-carbon-12));\n --color-primary-foreground: var(--primary-foreground, var(--color-neutral-min));\n\n --color-secondary: var(--secondary, var(--color-neutral-5));\n --color-secondary-foreground: var(--secondary-foreground, var(--color-neutral-9));\n\n --color-accent: var(--accent, var(--color-neutral-8));\n --color-accent-foreground: var(--accent-foreground, var(--color-neutral-10));\n\n --color-muted: var(--muted, var(--color-neutral-3));\n --color-muted-foreground: var(--muted-foreground, var(--color-neutral-9));\n\n --color-border: var(--border, var(--color-neutral-7));\n --color-ring: var(--ring, oklch(from var(--color-neutral-max) l c h / 10%));\n\n --color-info: var(--color-blue-3);\n --color-info-foreground: var(--color-blue-9);\n --color-success: var(--color-green-3);\n --color-success-foreground: var(--color-green-9);\n --color-warning: var(--color-yellow-3);\n --color-warning-foreground: var(--color-yellow-11);\n\n --color-destructive: var(--destructive, var(--color-red-4));\n --color-destructive-foreground: var(--destructive-foreground, var(--color-red-9));\n --color-destructive-border: var(--color-red-10);\n\n --color-popover: var(--popover, var(--color-neutral-min));\n --color-popover-foreground: var(--popover-foreground, var(--color-neutral-12));\n\n --color-input: var(--input, var(--color-neutral-min));\n --color-input-foreground: var(--color-neutral-12);\n --color-input-muted: var(--color-neutral-3);\n\n --shadow-bevel-xs:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%);\n --shadow-bevel-sm:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%);\n --shadow-bevel-md:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%);\n --shadow-bevel-lg:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 6px 3px -6px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-bevel-xl:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 6px 3px -6px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 12px 6px -12px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-bevel-2xl:\n 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 1px 1px -1px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 2px 1px -2px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 4px 2px -4px oklch(from var(--color-neutral-max) l c h / 5%),\n 0px 6px 3px -6px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 12px 6px -12px oklch(from var(--color-neutral-max) l c h / 10%),\n 0px 24px 12px -24px oklch(from var(--color-neutral-max) l c h / 10%);\n\n --shadow-button-resting: none;\n --shadow-button-hover: none;\n\n --shadow-button-destructive-resting: none;\n --shadow-button-destructive-hover: none;\n\n --shadow-button-outlined-resting: none;\n --shadow-button-outlined-hover: none;\n\n --shadow-input-resting: 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 10%);\n --shadow-input-hover: 0px 0px 0px 1px oklch(from var(--color-neutral-max) l c h / 20%);\n --shadow-input-destructive-resting: 0px 0px 0px 1px\n oklch(from var(--color-destructive-border) l c h / 25%);\n --shadow-input-destructive-hover: 0px 0px 0px 1px\n oklch(from var(--color-destructive-border) l c h / 50%);\n\n --shadow-checkbox-resting: none;\n --shadow-checkbox-hover: none;\n\n --shadow-switch-resting: none;\n --shadow-switch-hover: none;\n --shadow-switch-focus: none;\n --shadow-switch-thumb: none;\n\n --radius-xs: 8px;\n --radius-sm: 10px;\n --radius-md: 12px;\n --radius-lg: 14px;\n --radius-xl: 16px;\n --radius-2xl: 20px;\n --radius-3xl: 24px;\n --radius-4xl: 32px;\n --radius-5xl: 36px;\n --radius-6xl: 40px;\n --radius-7xl: 48px;\n --radius-8xl: 56px;\n --radius-9xl: 64px;\n }\n}\n",
"type": "registry:file",
"target": "auth0-ui-components/styles/themes/rounded.css"
}
]
}