@flamingo-stack/openframe-frontend-core 0.0.434-snapshot.20260716100758 → 0.0.434
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-32V2VHPE.cjs → chunk-473VV632.cjs} +26 -26
- package/dist/{chunk-32V2VHPE.cjs.map → chunk-473VV632.cjs.map} +1 -1
- package/dist/{chunk-FSOKLOXF.js → chunk-6CFMFNIB.js} +2 -2
- package/dist/{chunk-ZH2OEMQJ.js → chunk-6PTETC3Z.js} +157 -134
- package/dist/{chunk-ZH2OEMQJ.js.map → chunk-6PTETC3Z.js.map} +1 -1
- package/dist/{chunk-32BSKGEI.js → chunk-7E2DFRIK.js} +2 -2
- package/dist/{chunk-3V5UQ5TU.cjs → chunk-7R3PASHE.cjs} +541 -518
- package/dist/chunk-7R3PASHE.cjs.map +1 -0
- package/dist/{chunk-MWIYAVFT.js → chunk-A6KQMTJV.js} +4 -4
- package/dist/{chunk-2WXQFYNC.js → chunk-AHXDYVAE.js} +2 -2
- package/dist/{chunk-2QJNX32P.cjs → chunk-AOWQU2KB.cjs} +5 -5
- package/dist/{chunk-2QJNX32P.cjs.map → chunk-AOWQU2KB.cjs.map} +1 -1
- package/dist/{chunk-PXTDEKAY.cjs → chunk-B77THL7Y.cjs} +7 -7
- package/dist/{chunk-PXTDEKAY.cjs.map → chunk-B77THL7Y.cjs.map} +1 -1
- package/dist/{chunk-E6NRV33G.cjs → chunk-BSTVI23E.cjs} +11 -11
- package/dist/{chunk-E6NRV33G.cjs.map → chunk-BSTVI23E.cjs.map} +1 -1
- package/dist/{chunk-AUSUEKXY.cjs → chunk-C476N6PJ.cjs} +31 -31
- package/dist/{chunk-AUSUEKXY.cjs.map → chunk-C476N6PJ.cjs.map} +1 -1
- package/dist/{chunk-WXNE2BF4.cjs → chunk-CV3JHPLQ.cjs} +37 -37
- package/dist/{chunk-WXNE2BF4.cjs.map → chunk-CV3JHPLQ.cjs.map} +1 -1
- package/dist/{chunk-IWYRSGJU.cjs → chunk-F2VLV4PD.cjs} +9 -9
- package/dist/{chunk-IWYRSGJU.cjs.map → chunk-F2VLV4PD.cjs.map} +1 -1
- package/dist/{chunk-KVXB3FOB.cjs → chunk-FEOHPHJ5.cjs} +62 -62
- package/dist/{chunk-KVXB3FOB.cjs.map → chunk-FEOHPHJ5.cjs.map} +1 -1
- package/dist/{chunk-DVYA3BDU.js → chunk-KFXA4ZG3.js} +4 -4
- package/dist/{chunk-BMEA5NPX.js → chunk-NBWZW22E.js} +4 -4
- package/dist/{chunk-NGBO5Z5O.cjs → chunk-P6VXTG5N.cjs} +15 -15
- package/dist/{chunk-NGBO5Z5O.cjs.map → chunk-P6VXTG5N.cjs.map} +1 -1
- package/dist/{chunk-GQHXJ37C.js → chunk-PAOY2AIG.js} +2 -2
- package/dist/{chunk-NFU37EP6.js → chunk-RZRQI55M.js} +2 -2
- package/dist/{chunk-NRIJNBRG.cjs → chunk-SXVO2PXE.cjs} +26 -26
- package/dist/{chunk-NRIJNBRG.cjs.map → chunk-SXVO2PXE.cjs.map} +1 -1
- package/dist/{chunk-P5EN67AU.cjs → chunk-WPMUNLCC.cjs} +59 -59
- package/dist/{chunk-P5EN67AU.cjs.map → chunk-WPMUNLCC.cjs.map} +1 -1
- package/dist/{chunk-LYK6D7GU.js → chunk-XWEECWZD.js} +2 -2
- package/dist/{chunk-3OPSNUPJ.js → chunk-ZAJPJ2JD.js} +2 -2
- package/dist/{chunk-E77Z2P3K.js → chunk-ZB57GGZX.js} +4 -4
- 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 +4 -8
- package/dist/components/features/auth/create-organization-form.d.ts.map +1 -1
- package/dist/components/features/auth/login-form.d.ts +14 -18
- package/dist/components/features/auth/login-form.d.ts.map +1 -1
- package/dist/components/features/auth/sso-providers.d.ts +1 -7
- 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 +28 -37
- package/src/components/features/auth/login-form.tsx +60 -29
- package/src/components/features/auth/sso-providers.tsx +1 -8
- package/dist/chunk-3V5UQ5TU.cjs.map +0 -1
- /package/dist/{chunk-FSOKLOXF.js.map → chunk-6CFMFNIB.js.map} +0 -0
- /package/dist/{chunk-32BSKGEI.js.map → chunk-7E2DFRIK.js.map} +0 -0
- /package/dist/{chunk-MWIYAVFT.js.map → chunk-A6KQMTJV.js.map} +0 -0
- /package/dist/{chunk-2WXQFYNC.js.map → chunk-AHXDYVAE.js.map} +0 -0
- /package/dist/{chunk-DVYA3BDU.js.map → chunk-KFXA4ZG3.js.map} +0 -0
- /package/dist/{chunk-BMEA5NPX.js.map → chunk-NBWZW22E.js.map} +0 -0
- /package/dist/{chunk-GQHXJ37C.js.map → chunk-PAOY2AIG.js.map} +0 -0
- /package/dist/{chunk-NFU37EP6.js.map → chunk-RZRQI55M.js.map} +0 -0
- /package/dist/{chunk-LYK6D7GU.js.map → chunk-XWEECWZD.js.map} +0 -0
- /package/dist/{chunk-3OPSNUPJ.js.map → chunk-ZAJPJ2JD.js.map} +0 -0
- /package/dist/{chunk-E77Z2P3K.js.map → chunk-ZB57GGZX.js.map} +0 -0
|
@@ -3,6 +3,7 @@
|
|
|
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'
|
|
6
7
|
import { Input } from '../../ui/input'
|
|
7
8
|
import type { AuthSsoProvider } from './sso-providers'
|
|
8
9
|
import { SsoProviderButtons } from './sso-providers'
|
|
@@ -11,26 +12,26 @@ export interface LoginFormProps {
|
|
|
11
12
|
/** Controlled email value */
|
|
12
13
|
email: string
|
|
13
14
|
onEmailChange: (value: string) => void
|
|
14
|
-
/**
|
|
15
|
-
onSubmit
|
|
15
|
+
/** Primary submit ("Continue") */
|
|
16
|
+
onSubmit: () => void
|
|
17
|
+
/** When set, renders a "Forgot Password?" button next to Continue. */
|
|
18
|
+
onForgotPassword?: () => void
|
|
16
19
|
emailPlaceholder?: string
|
|
20
|
+
submitLabel?: string
|
|
21
|
+
forgotPasswordLabel?: string
|
|
22
|
+
/** Disables just the primary submit (field stays editable). */
|
|
23
|
+
submitDisabled?: boolean
|
|
17
24
|
loading?: boolean
|
|
18
25
|
disabled?: boolean
|
|
19
26
|
errors?: {
|
|
20
27
|
email?: string
|
|
21
28
|
}
|
|
22
|
-
/** Informational status under the email field (e.g. live tenant discovery). `errors.email` wins. */
|
|
23
|
-
emailStatus?: { message: string; variant: 'error' | 'warning' | 'success' | 'muted' }
|
|
24
29
|
/**
|
|
25
|
-
* SSO providers
|
|
26
|
-
*
|
|
30
|
+
* SSO providers to offer. When non-empty the form switches to SSO mode:
|
|
31
|
+
* the primary submit is replaced by a stack of provider buttons.
|
|
27
32
|
*/
|
|
28
|
-
ssoProviders
|
|
33
|
+
ssoProviders?: AuthSsoProvider[]
|
|
29
34
|
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[]
|
|
34
35
|
/** Verb prefix for provider buttons, e.g. "Continue with". Ignored for "openframe". */
|
|
35
36
|
ssoActionLabel?: string
|
|
36
37
|
className?: string
|
|
@@ -38,34 +39,35 @@ export interface LoginFormProps {
|
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* Login form (Login tab). Presentational + controlled — the consumer owns
|
|
41
|
-
* state, validation and
|
|
42
|
-
*
|
|
43
|
-
* consumer validates the email (real-time tenant discovery).
|
|
42
|
+
* state, validation and submission. Covers the empty and SSO states from the
|
|
43
|
+
* auth redesign: enter an email, then Continue or pick an SSO provider.
|
|
44
44
|
*/
|
|
45
45
|
export function LoginForm({
|
|
46
46
|
email,
|
|
47
47
|
onEmailChange,
|
|
48
48
|
onSubmit,
|
|
49
|
+
onForgotPassword,
|
|
49
50
|
emailPlaceholder = 'username@mail.com',
|
|
51
|
+
submitLabel = 'Continue',
|
|
52
|
+
forgotPasswordLabel = 'Forgot Password?',
|
|
53
|
+
submitDisabled = false,
|
|
50
54
|
loading = false,
|
|
51
55
|
disabled = false,
|
|
52
56
|
errors,
|
|
53
|
-
emailStatus,
|
|
54
57
|
ssoProviders,
|
|
55
58
|
onSsoClick,
|
|
56
|
-
ssoDisabled = false,
|
|
57
|
-
ssoEnabledProviders,
|
|
58
59
|
ssoActionLabel = 'Continue with',
|
|
59
60
|
className,
|
|
60
61
|
}: LoginFormProps) {
|
|
61
|
-
const
|
|
62
|
+
const isSsoMode = !!ssoProviders && ssoProviders.length > 0
|
|
63
|
+
const fieldDisabled = disabled || loading || isSsoMode
|
|
62
64
|
|
|
63
65
|
// Validation messages are deferred while the user is typing (shown on blur or after a pause).
|
|
64
66
|
const emailErr = useDeferredError(errors?.email, email)
|
|
65
67
|
|
|
66
68
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
67
69
|
if (event.key === 'Enter' && !fieldDisabled) {
|
|
68
|
-
onSubmit
|
|
70
|
+
onSubmit()
|
|
69
71
|
}
|
|
70
72
|
}
|
|
71
73
|
|
|
@@ -88,22 +90,51 @@ export function LoginForm({
|
|
|
88
90
|
label="Email"
|
|
89
91
|
placeholder={emailPlaceholder}
|
|
90
92
|
value={email}
|
|
91
|
-
error={emailErr.error
|
|
92
|
-
errorVariant={emailErr.error ? 'error' : emailStatus?.variant}
|
|
93
|
+
error={emailErr.error}
|
|
93
94
|
disabled={fieldDisabled}
|
|
94
95
|
onBlur={emailErr.onBlur}
|
|
95
96
|
onChange={(event) => onEmailChange(event.target.value)}
|
|
96
97
|
onKeyDown={handleKeyDown}
|
|
97
98
|
/>
|
|
98
99
|
|
|
99
|
-
{/*
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
{/* Actions */}
|
|
101
|
+
{isSsoMode ? (
|
|
102
|
+
<SsoProviderButtons
|
|
103
|
+
providers={ssoProviders!}
|
|
104
|
+
onSsoClick={onSsoClick}
|
|
105
|
+
actionLabel={ssoActionLabel}
|
|
106
|
+
disabled={disabled || loading}
|
|
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
|
+
)}
|
|
107
138
|
</div>
|
|
108
139
|
)
|
|
109
140
|
}
|
|
@@ -33,12 +33,6 @@ 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[]
|
|
42
36
|
}
|
|
43
37
|
|
|
44
38
|
/** Stacked full-width SSO provider buttons shared by the auth forms. */
|
|
@@ -47,7 +41,6 @@ export function SsoProviderButtons({
|
|
|
47
41
|
onSsoClick,
|
|
48
42
|
actionLabel = 'Continue with',
|
|
49
43
|
disabled = false,
|
|
50
|
-
enabledProviders,
|
|
51
44
|
}: SsoProviderButtonsProps) {
|
|
52
45
|
return (
|
|
53
46
|
<div className="flex flex-col gap-[var(--spacing-system-l)]">
|
|
@@ -60,7 +53,7 @@ export function SsoProviderButtons({
|
|
|
60
53
|
type="button"
|
|
61
54
|
variant="outline"
|
|
62
55
|
fullWidth
|
|
63
|
-
disabled={disabled
|
|
56
|
+
disabled={disabled}
|
|
64
57
|
// Disabled buttons recede to the page background (like a disabled input), per design
|
|
65
58
|
className="disabled:bg-ods-bg"
|
|
66
59
|
leftIcon={<Icon className="h-5 w-5" />}
|