@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.
Files changed (89) hide show
  1. package/dist/{chunk-32V2VHPE.cjs → chunk-473VV632.cjs} +26 -26
  2. package/dist/{chunk-32V2VHPE.cjs.map → chunk-473VV632.cjs.map} +1 -1
  3. package/dist/{chunk-FSOKLOXF.js → chunk-6CFMFNIB.js} +2 -2
  4. package/dist/{chunk-ZH2OEMQJ.js → chunk-6PTETC3Z.js} +157 -134
  5. package/dist/{chunk-ZH2OEMQJ.js.map → chunk-6PTETC3Z.js.map} +1 -1
  6. package/dist/{chunk-32BSKGEI.js → chunk-7E2DFRIK.js} +2 -2
  7. package/dist/{chunk-3V5UQ5TU.cjs → chunk-7R3PASHE.cjs} +541 -518
  8. package/dist/chunk-7R3PASHE.cjs.map +1 -0
  9. package/dist/{chunk-MWIYAVFT.js → chunk-A6KQMTJV.js} +4 -4
  10. package/dist/{chunk-2WXQFYNC.js → chunk-AHXDYVAE.js} +2 -2
  11. package/dist/{chunk-2QJNX32P.cjs → chunk-AOWQU2KB.cjs} +5 -5
  12. package/dist/{chunk-2QJNX32P.cjs.map → chunk-AOWQU2KB.cjs.map} +1 -1
  13. package/dist/{chunk-PXTDEKAY.cjs → chunk-B77THL7Y.cjs} +7 -7
  14. package/dist/{chunk-PXTDEKAY.cjs.map → chunk-B77THL7Y.cjs.map} +1 -1
  15. package/dist/{chunk-E6NRV33G.cjs → chunk-BSTVI23E.cjs} +11 -11
  16. package/dist/{chunk-E6NRV33G.cjs.map → chunk-BSTVI23E.cjs.map} +1 -1
  17. package/dist/{chunk-AUSUEKXY.cjs → chunk-C476N6PJ.cjs} +31 -31
  18. package/dist/{chunk-AUSUEKXY.cjs.map → chunk-C476N6PJ.cjs.map} +1 -1
  19. package/dist/{chunk-WXNE2BF4.cjs → chunk-CV3JHPLQ.cjs} +37 -37
  20. package/dist/{chunk-WXNE2BF4.cjs.map → chunk-CV3JHPLQ.cjs.map} +1 -1
  21. package/dist/{chunk-IWYRSGJU.cjs → chunk-F2VLV4PD.cjs} +9 -9
  22. package/dist/{chunk-IWYRSGJU.cjs.map → chunk-F2VLV4PD.cjs.map} +1 -1
  23. package/dist/{chunk-KVXB3FOB.cjs → chunk-FEOHPHJ5.cjs} +62 -62
  24. package/dist/{chunk-KVXB3FOB.cjs.map → chunk-FEOHPHJ5.cjs.map} +1 -1
  25. package/dist/{chunk-DVYA3BDU.js → chunk-KFXA4ZG3.js} +4 -4
  26. package/dist/{chunk-BMEA5NPX.js → chunk-NBWZW22E.js} +4 -4
  27. package/dist/{chunk-NGBO5Z5O.cjs → chunk-P6VXTG5N.cjs} +15 -15
  28. package/dist/{chunk-NGBO5Z5O.cjs.map → chunk-P6VXTG5N.cjs.map} +1 -1
  29. package/dist/{chunk-GQHXJ37C.js → chunk-PAOY2AIG.js} +2 -2
  30. package/dist/{chunk-NFU37EP6.js → chunk-RZRQI55M.js} +2 -2
  31. package/dist/{chunk-NRIJNBRG.cjs → chunk-SXVO2PXE.cjs} +26 -26
  32. package/dist/{chunk-NRIJNBRG.cjs.map → chunk-SXVO2PXE.cjs.map} +1 -1
  33. package/dist/{chunk-P5EN67AU.cjs → chunk-WPMUNLCC.cjs} +59 -59
  34. package/dist/{chunk-P5EN67AU.cjs.map → chunk-WPMUNLCC.cjs.map} +1 -1
  35. package/dist/{chunk-LYK6D7GU.js → chunk-XWEECWZD.js} +2 -2
  36. package/dist/{chunk-3OPSNUPJ.js → chunk-ZAJPJ2JD.js} +2 -2
  37. package/dist/{chunk-E77Z2P3K.js → chunk-ZB57GGZX.js} +4 -4
  38. package/dist/components/case-studies/index.cjs +8 -8
  39. package/dist/components/case-studies/index.js +2 -2
  40. package/dist/components/chat/index.cjs +2 -2
  41. package/dist/components/chat/index.js +1 -1
  42. package/dist/components/contact/index.cjs +3 -3
  43. package/dist/components/contact/index.js +2 -2
  44. package/dist/components/docs/index.cjs +5 -5
  45. package/dist/components/docs/index.js +4 -4
  46. package/dist/components/embeds/index.cjs +3 -3
  47. package/dist/components/embeds/index.js +2 -2
  48. package/dist/components/faq/index.cjs +3 -3
  49. package/dist/components/faq/index.js +2 -2
  50. package/dist/components/features/auth/create-organization-form.d.ts +4 -8
  51. package/dist/components/features/auth/create-organization-form.d.ts.map +1 -1
  52. package/dist/components/features/auth/login-form.d.ts +14 -18
  53. package/dist/components/features/auth/login-form.d.ts.map +1 -1
  54. package/dist/components/features/auth/sso-providers.d.ts +1 -7
  55. package/dist/components/features/auth/sso-providers.d.ts.map +1 -1
  56. package/dist/components/features/index.cjs +2 -2
  57. package/dist/components/features/index.js +1 -1
  58. package/dist/components/help-center-pages/index.cjs +20 -20
  59. package/dist/components/help-center-pages/index.js +11 -11
  60. package/dist/components/index.cjs +128 -128
  61. package/dist/components/index.js +9 -9
  62. package/dist/components/navigation/index.cjs +2 -2
  63. package/dist/components/navigation/index.js +1 -1
  64. package/dist/components/onboarding-guides/index.cjs +5 -5
  65. package/dist/components/onboarding-guides/index.js +4 -4
  66. package/dist/components/related-content/index.cjs +3 -3
  67. package/dist/components/related-content/index.js +2 -2
  68. package/dist/components/tickets/index.cjs +5 -5
  69. package/dist/components/tickets/index.js +4 -4
  70. package/dist/components/ui/index.cjs +2 -2
  71. package/dist/components/ui/index.js +1 -1
  72. package/dist/index.cjs +2 -2
  73. package/dist/index.js +1 -1
  74. package/package.json +1 -1
  75. package/src/components/features/auth/create-organization-form.tsx +28 -37
  76. package/src/components/features/auth/login-form.tsx +60 -29
  77. package/src/components/features/auth/sso-providers.tsx +1 -8
  78. package/dist/chunk-3V5UQ5TU.cjs.map +0 -1
  79. /package/dist/{chunk-FSOKLOXF.js.map → chunk-6CFMFNIB.js.map} +0 -0
  80. /package/dist/{chunk-32BSKGEI.js.map → chunk-7E2DFRIK.js.map} +0 -0
  81. /package/dist/{chunk-MWIYAVFT.js.map → chunk-A6KQMTJV.js.map} +0 -0
  82. /package/dist/{chunk-2WXQFYNC.js.map → chunk-AHXDYVAE.js.map} +0 -0
  83. /package/dist/{chunk-DVYA3BDU.js.map → chunk-KFXA4ZG3.js.map} +0 -0
  84. /package/dist/{chunk-BMEA5NPX.js.map → chunk-NBWZW22E.js.map} +0 -0
  85. /package/dist/{chunk-GQHXJ37C.js.map → chunk-PAOY2AIG.js.map} +0 -0
  86. /package/dist/{chunk-NFU37EP6.js.map → chunk-RZRQI55M.js.map} +0 -0
  87. /package/dist/{chunk-LYK6D7GU.js.map → chunk-XWEECWZD.js.map} +0 -0
  88. /package/dist/{chunk-3OPSNUPJ.js.map → chunk-ZAJPJ2JD.js.map} +0 -0
  89. /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
- /** Enter-key handler on the email field (optional). */
15
- onSubmit?: () => void
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 rendered below the email field. Always visible; gate
26
- * clickability with `ssoDisabled` / `ssoEnabledProviders`.
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: AuthSsoProvider[]
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 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).
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 fieldDisabled = disabled || loading
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 ?? emailStatus?.message}
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
- {/* 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
- />
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 || (enabledProviders ? !enabledProviders.includes(provider) : false)}
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" />}