@flamingo-stack/openframe-frontend-core 0.0.434 → 0.0.435
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-AOWQU2KB.cjs → chunk-2QJNX32P.cjs} +5 -5
- package/dist/{chunk-AOWQU2KB.cjs.map → chunk-2QJNX32P.cjs.map} +1 -1
- package/dist/{chunk-AHXDYVAE.js → chunk-2WXQFYNC.js} +2 -2
- package/dist/{chunk-7E2DFRIK.js → chunk-32BSKGEI.js} +2 -2
- package/dist/{chunk-473VV632.cjs → chunk-32V2VHPE.cjs} +26 -26
- package/dist/{chunk-473VV632.cjs.map → chunk-32V2VHPE.cjs.map} +1 -1
- package/dist/{chunk-ZAJPJ2JD.js → chunk-3OPSNUPJ.js} +2 -2
- package/dist/{chunk-7R3PASHE.cjs → chunk-3V5UQ5TU.cjs} +518 -541
- package/dist/chunk-3V5UQ5TU.cjs.map +1 -0
- package/dist/{chunk-C476N6PJ.cjs → chunk-AUSUEKXY.cjs} +31 -31
- package/dist/{chunk-C476N6PJ.cjs.map → chunk-AUSUEKXY.cjs.map} +1 -1
- package/dist/{chunk-NBWZW22E.js → chunk-BMEA5NPX.js} +4 -4
- package/dist/{chunk-KFXA4ZG3.js → chunk-DVYA3BDU.js} +4 -4
- package/dist/{chunk-BSTVI23E.cjs → chunk-E6NRV33G.cjs} +11 -11
- package/dist/{chunk-BSTVI23E.cjs.map → chunk-E6NRV33G.cjs.map} +1 -1
- package/dist/{chunk-ZB57GGZX.js → chunk-E77Z2P3K.js} +4 -4
- package/dist/{chunk-6CFMFNIB.js → chunk-FSOKLOXF.js} +2 -2
- package/dist/{chunk-PAOY2AIG.js → chunk-GQHXJ37C.js} +2 -2
- package/dist/{chunk-F2VLV4PD.cjs → chunk-IWYRSGJU.cjs} +9 -9
- package/dist/{chunk-F2VLV4PD.cjs.map → chunk-IWYRSGJU.cjs.map} +1 -1
- package/dist/{chunk-FEOHPHJ5.cjs → chunk-KVXB3FOB.cjs} +62 -62
- package/dist/{chunk-FEOHPHJ5.cjs.map → chunk-KVXB3FOB.cjs.map} +1 -1
- package/dist/{chunk-XWEECWZD.js → chunk-LYK6D7GU.js} +2 -2
- package/dist/{chunk-A6KQMTJV.js → chunk-MWIYAVFT.js} +4 -4
- package/dist/{chunk-RZRQI55M.js → chunk-NFU37EP6.js} +2 -2
- package/dist/{chunk-P6VXTG5N.cjs → chunk-NGBO5Z5O.cjs} +15 -15
- package/dist/{chunk-P6VXTG5N.cjs.map → chunk-NGBO5Z5O.cjs.map} +1 -1
- package/dist/{chunk-SXVO2PXE.cjs → chunk-NRIJNBRG.cjs} +26 -26
- package/dist/{chunk-SXVO2PXE.cjs.map → chunk-NRIJNBRG.cjs.map} +1 -1
- package/dist/{chunk-WPMUNLCC.cjs → chunk-P5EN67AU.cjs} +59 -59
- package/dist/{chunk-WPMUNLCC.cjs.map → chunk-P5EN67AU.cjs.map} +1 -1
- package/dist/{chunk-B77THL7Y.cjs → chunk-PXTDEKAY.cjs} +7 -7
- package/dist/{chunk-B77THL7Y.cjs.map → chunk-PXTDEKAY.cjs.map} +1 -1
- package/dist/{chunk-CV3JHPLQ.cjs → chunk-WXNE2BF4.cjs} +37 -37
- package/dist/{chunk-CV3JHPLQ.cjs.map → chunk-WXNE2BF4.cjs.map} +1 -1
- package/dist/{chunk-6PTETC3Z.js → chunk-ZH2OEMQJ.js} +134 -157
- package/dist/{chunk-6PTETC3Z.js.map → chunk-ZH2OEMQJ.js.map} +1 -1
- package/dist/components/case-studies/index.cjs +8 -8
- package/dist/components/case-studies/index.js +2 -2
- package/dist/components/chat/index.cjs +2 -2
- package/dist/components/chat/index.js +1 -1
- package/dist/components/contact/index.cjs +3 -3
- package/dist/components/contact/index.js +2 -2
- package/dist/components/docs/index.cjs +5 -5
- package/dist/components/docs/index.js +4 -4
- package/dist/components/embeds/index.cjs +3 -3
- package/dist/components/embeds/index.js +2 -2
- package/dist/components/faq/index.cjs +3 -3
- package/dist/components/faq/index.js +2 -2
- package/dist/components/features/auth/create-organization-form.d.ts +8 -4
- package/dist/components/features/auth/create-organization-form.d.ts.map +1 -1
- package/dist/components/features/auth/login-form.d.ts +18 -14
- package/dist/components/features/auth/login-form.d.ts.map +1 -1
- package/dist/components/features/auth/sso-providers.d.ts +7 -1
- package/dist/components/features/auth/sso-providers.d.ts.map +1 -1
- package/dist/components/features/index.cjs +2 -2
- package/dist/components/features/index.js +1 -1
- package/dist/components/help-center-pages/index.cjs +20 -20
- package/dist/components/help-center-pages/index.js +11 -11
- package/dist/components/index.cjs +128 -128
- package/dist/components/index.js +9 -9
- package/dist/components/navigation/index.cjs +2 -2
- package/dist/components/navigation/index.js +1 -1
- package/dist/components/onboarding-guides/index.cjs +5 -5
- package/dist/components/onboarding-guides/index.js +4 -4
- package/dist/components/related-content/index.cjs +3 -3
- package/dist/components/related-content/index.js +2 -2
- package/dist/components/tickets/index.cjs +5 -5
- package/dist/components/tickets/index.js +4 -4
- package/dist/components/ui/index.cjs +2 -2
- package/dist/components/ui/index.js +1 -1
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/components/features/auth/create-organization-form.tsx +37 -28
- package/src/components/features/auth/login-form.tsx +29 -60
- package/src/components/features/auth/sso-providers.tsx +8 -1
- package/dist/chunk-7R3PASHE.cjs.map +0 -1
- /package/dist/{chunk-AHXDYVAE.js.map → chunk-2WXQFYNC.js.map} +0 -0
- /package/dist/{chunk-7E2DFRIK.js.map → chunk-32BSKGEI.js.map} +0 -0
- /package/dist/{chunk-ZAJPJ2JD.js.map → chunk-3OPSNUPJ.js.map} +0 -0
- /package/dist/{chunk-NBWZW22E.js.map → chunk-BMEA5NPX.js.map} +0 -0
- /package/dist/{chunk-KFXA4ZG3.js.map → chunk-DVYA3BDU.js.map} +0 -0
- /package/dist/{chunk-ZB57GGZX.js.map → chunk-E77Z2P3K.js.map} +0 -0
- /package/dist/{chunk-6CFMFNIB.js.map → chunk-FSOKLOXF.js.map} +0 -0
- /package/dist/{chunk-PAOY2AIG.js.map → chunk-GQHXJ37C.js.map} +0 -0
- /package/dist/{chunk-XWEECWZD.js.map → chunk-LYK6D7GU.js.map} +0 -0
- /package/dist/{chunk-A6KQMTJV.js.map → chunk-MWIYAVFT.js.map} +0 -0
- /package/dist/{chunk-RZRQI55M.js.map → chunk-NFU37EP6.js.map} +0 -0
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import type * as React from 'react'
|
|
4
4
|
import { cn } from '../../../utils/cn'
|
|
5
5
|
import { useDeferredError } from '../../../hooks/ui/use-deferred-error'
|
|
6
|
-
import { Button } from '../../ui/button'
|
|
7
6
|
import { Input } from '../../ui/input'
|
|
8
7
|
import type { AuthSsoProvider } from './sso-providers'
|
|
9
8
|
import { SsoProviderButtons } from './sso-providers'
|
|
@@ -12,26 +11,26 @@ export interface LoginFormProps {
|
|
|
12
11
|
/** Controlled email value */
|
|
13
12
|
email: string
|
|
14
13
|
onEmailChange: (value: string) => void
|
|
15
|
-
/**
|
|
16
|
-
onSubmit
|
|
17
|
-
/** When set, renders a "Forgot Password?" button next to Continue. */
|
|
18
|
-
onForgotPassword?: () => void
|
|
14
|
+
/** Enter-key handler on the email field (optional). */
|
|
15
|
+
onSubmit?: () => void
|
|
19
16
|
emailPlaceholder?: string
|
|
20
|
-
submitLabel?: string
|
|
21
|
-
forgotPasswordLabel?: string
|
|
22
|
-
/** Disables just the primary submit (field stays editable). */
|
|
23
|
-
submitDisabled?: boolean
|
|
24
17
|
loading?: boolean
|
|
25
18
|
disabled?: boolean
|
|
26
19
|
errors?: {
|
|
27
20
|
email?: string
|
|
28
21
|
}
|
|
22
|
+
/** Informational status under the email field (e.g. live tenant discovery). `errors.email` wins. */
|
|
23
|
+
emailStatus?: { message: string; variant: 'error' | 'warning' | 'success' | 'muted' }
|
|
29
24
|
/**
|
|
30
|
-
* SSO providers
|
|
31
|
-
*
|
|
25
|
+
* SSO providers rendered below the email field. Always visible; gate
|
|
26
|
+
* clickability with `ssoDisabled` / `ssoEnabledProviders`.
|
|
32
27
|
*/
|
|
33
|
-
ssoProviders
|
|
28
|
+
ssoProviders: AuthSsoProvider[]
|
|
34
29
|
onSsoClick?: (provider: AuthSsoProvider) => void
|
|
30
|
+
/** Disables every provider button (e.g. until the email passes discovery). */
|
|
31
|
+
ssoDisabled?: boolean
|
|
32
|
+
/** When set, only these providers are clickable; the rest stay disabled. */
|
|
33
|
+
ssoEnabledProviders?: AuthSsoProvider[]
|
|
35
34
|
/** Verb prefix for provider buttons, e.g. "Continue with". Ignored for "openframe". */
|
|
36
35
|
ssoActionLabel?: string
|
|
37
36
|
className?: string
|
|
@@ -39,35 +38,34 @@ export interface LoginFormProps {
|
|
|
39
38
|
|
|
40
39
|
/**
|
|
41
40
|
* Login form (Login tab). Presentational + controlled — the consumer owns
|
|
42
|
-
* state, validation and
|
|
43
|
-
*
|
|
41
|
+
* state, validation and discovery. Single-screen design: the email field and
|
|
42
|
+
* the SSO provider buttons are always visible; the buttons unlock once the
|
|
43
|
+
* consumer validates the email (real-time tenant discovery).
|
|
44
44
|
*/
|
|
45
45
|
export function LoginForm({
|
|
46
46
|
email,
|
|
47
47
|
onEmailChange,
|
|
48
48
|
onSubmit,
|
|
49
|
-
onForgotPassword,
|
|
50
49
|
emailPlaceholder = 'username@mail.com',
|
|
51
|
-
submitLabel = 'Continue',
|
|
52
|
-
forgotPasswordLabel = 'Forgot Password?',
|
|
53
|
-
submitDisabled = false,
|
|
54
50
|
loading = false,
|
|
55
51
|
disabled = false,
|
|
56
52
|
errors,
|
|
53
|
+
emailStatus,
|
|
57
54
|
ssoProviders,
|
|
58
55
|
onSsoClick,
|
|
56
|
+
ssoDisabled = false,
|
|
57
|
+
ssoEnabledProviders,
|
|
59
58
|
ssoActionLabel = 'Continue with',
|
|
60
59
|
className,
|
|
61
60
|
}: LoginFormProps) {
|
|
62
|
-
const
|
|
63
|
-
const fieldDisabled = disabled || loading || isSsoMode
|
|
61
|
+
const fieldDisabled = disabled || loading
|
|
64
62
|
|
|
65
63
|
// Validation messages are deferred while the user is typing (shown on blur or after a pause).
|
|
66
64
|
const emailErr = useDeferredError(errors?.email, email)
|
|
67
65
|
|
|
68
66
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
69
67
|
if (event.key === 'Enter' && !fieldDisabled) {
|
|
70
|
-
onSubmit()
|
|
68
|
+
onSubmit?.()
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
|
|
@@ -90,51 +88,22 @@ export function LoginForm({
|
|
|
90
88
|
label="Email"
|
|
91
89
|
placeholder={emailPlaceholder}
|
|
92
90
|
value={email}
|
|
93
|
-
error={emailErr.error}
|
|
91
|
+
error={emailErr.error ?? emailStatus?.message}
|
|
92
|
+
errorVariant={emailErr.error ? 'error' : emailStatus?.variant}
|
|
94
93
|
disabled={fieldDisabled}
|
|
95
94
|
onBlur={emailErr.onBlur}
|
|
96
95
|
onChange={(event) => onEmailChange(event.target.value)}
|
|
97
96
|
onKeyDown={handleKeyDown}
|
|
98
97
|
/>
|
|
99
98
|
|
|
100
|
-
{/*
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
) : (
|
|
109
|
-
<div className="flex items-center gap-[var(--spacing-system-l)]">
|
|
110
|
-
{onForgotPassword ? (
|
|
111
|
-
<Button
|
|
112
|
-
type="button"
|
|
113
|
-
variant="transparent"
|
|
114
|
-
fullWidth
|
|
115
|
-
className="flex-1"
|
|
116
|
-
disabled={disabled || loading}
|
|
117
|
-
onClick={onForgotPassword}
|
|
118
|
-
>
|
|
119
|
-
{forgotPasswordLabel}
|
|
120
|
-
</Button>
|
|
121
|
-
) : (
|
|
122
|
-
// Spacer keeps the button on the right half, matching the design
|
|
123
|
-
<div className="hidden flex-1 md:block" />
|
|
124
|
-
)}
|
|
125
|
-
<Button
|
|
126
|
-
type="button"
|
|
127
|
-
variant="accent"
|
|
128
|
-
fullWidth
|
|
129
|
-
className={onForgotPassword ? 'flex-1' : 'md:flex-1'}
|
|
130
|
-
loading={loading}
|
|
131
|
-
disabled={disabled || submitDisabled}
|
|
132
|
-
onClick={onSubmit}
|
|
133
|
-
>
|
|
134
|
-
{submitLabel}
|
|
135
|
-
</Button>
|
|
136
|
-
</div>
|
|
137
|
-
)}
|
|
99
|
+
{/* SSO providers — always visible, unlocked by the consumer */}
|
|
100
|
+
<SsoProviderButtons
|
|
101
|
+
providers={ssoProviders}
|
|
102
|
+
onSsoClick={onSsoClick}
|
|
103
|
+
actionLabel={ssoActionLabel}
|
|
104
|
+
disabled={disabled || loading || ssoDisabled}
|
|
105
|
+
enabledProviders={ssoEnabledProviders}
|
|
106
|
+
/>
|
|
138
107
|
</div>
|
|
139
108
|
)
|
|
140
109
|
}
|
|
@@ -33,6 +33,12 @@ export interface SsoProviderButtonsProps {
|
|
|
33
33
|
/** Verb prefix for provider buttons, e.g. "Continue with". Ignored for "openframe". */
|
|
34
34
|
actionLabel?: string
|
|
35
35
|
disabled?: boolean
|
|
36
|
+
/**
|
|
37
|
+
* When set, only these providers are clickable and the rest render disabled —
|
|
38
|
+
* e.g. unlock just the providers a discovered tenant actually offers.
|
|
39
|
+
* `disabled` still wins over this list.
|
|
40
|
+
*/
|
|
41
|
+
enabledProviders?: AuthSsoProvider[]
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
/** Stacked full-width SSO provider buttons shared by the auth forms. */
|
|
@@ -41,6 +47,7 @@ export function SsoProviderButtons({
|
|
|
41
47
|
onSsoClick,
|
|
42
48
|
actionLabel = 'Continue with',
|
|
43
49
|
disabled = false,
|
|
50
|
+
enabledProviders,
|
|
44
51
|
}: SsoProviderButtonsProps) {
|
|
45
52
|
return (
|
|
46
53
|
<div className="flex flex-col gap-[var(--spacing-system-l)]">
|
|
@@ -53,7 +60,7 @@ export function SsoProviderButtons({
|
|
|
53
60
|
type="button"
|
|
54
61
|
variant="outline"
|
|
55
62
|
fullWidth
|
|
56
|
-
disabled={disabled}
|
|
63
|
+
disabled={disabled || (enabledProviders ? !enabledProviders.includes(provider) : false)}
|
|
57
64
|
// Disabled buttons recede to the page background (like a disabled input), per design
|
|
58
65
|
className="disabled:bg-ods-bg"
|
|
59
66
|
leftIcon={<Icon className="h-5 w-5" />}
|