@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.
Files changed (89) hide show
  1. package/dist/{chunk-AOWQU2KB.cjs → chunk-2QJNX32P.cjs} +5 -5
  2. package/dist/{chunk-AOWQU2KB.cjs.map → chunk-2QJNX32P.cjs.map} +1 -1
  3. package/dist/{chunk-AHXDYVAE.js → chunk-2WXQFYNC.js} +2 -2
  4. package/dist/{chunk-7E2DFRIK.js → chunk-32BSKGEI.js} +2 -2
  5. package/dist/{chunk-473VV632.cjs → chunk-32V2VHPE.cjs} +26 -26
  6. package/dist/{chunk-473VV632.cjs.map → chunk-32V2VHPE.cjs.map} +1 -1
  7. package/dist/{chunk-ZAJPJ2JD.js → chunk-3OPSNUPJ.js} +2 -2
  8. package/dist/{chunk-7R3PASHE.cjs → chunk-3V5UQ5TU.cjs} +518 -541
  9. package/dist/chunk-3V5UQ5TU.cjs.map +1 -0
  10. package/dist/{chunk-C476N6PJ.cjs → chunk-AUSUEKXY.cjs} +31 -31
  11. package/dist/{chunk-C476N6PJ.cjs.map → chunk-AUSUEKXY.cjs.map} +1 -1
  12. package/dist/{chunk-NBWZW22E.js → chunk-BMEA5NPX.js} +4 -4
  13. package/dist/{chunk-KFXA4ZG3.js → chunk-DVYA3BDU.js} +4 -4
  14. package/dist/{chunk-BSTVI23E.cjs → chunk-E6NRV33G.cjs} +11 -11
  15. package/dist/{chunk-BSTVI23E.cjs.map → chunk-E6NRV33G.cjs.map} +1 -1
  16. package/dist/{chunk-ZB57GGZX.js → chunk-E77Z2P3K.js} +4 -4
  17. package/dist/{chunk-6CFMFNIB.js → chunk-FSOKLOXF.js} +2 -2
  18. package/dist/{chunk-PAOY2AIG.js → chunk-GQHXJ37C.js} +2 -2
  19. package/dist/{chunk-F2VLV4PD.cjs → chunk-IWYRSGJU.cjs} +9 -9
  20. package/dist/{chunk-F2VLV4PD.cjs.map → chunk-IWYRSGJU.cjs.map} +1 -1
  21. package/dist/{chunk-FEOHPHJ5.cjs → chunk-KVXB3FOB.cjs} +62 -62
  22. package/dist/{chunk-FEOHPHJ5.cjs.map → chunk-KVXB3FOB.cjs.map} +1 -1
  23. package/dist/{chunk-XWEECWZD.js → chunk-LYK6D7GU.js} +2 -2
  24. package/dist/{chunk-A6KQMTJV.js → chunk-MWIYAVFT.js} +4 -4
  25. package/dist/{chunk-RZRQI55M.js → chunk-NFU37EP6.js} +2 -2
  26. package/dist/{chunk-P6VXTG5N.cjs → chunk-NGBO5Z5O.cjs} +15 -15
  27. package/dist/{chunk-P6VXTG5N.cjs.map → chunk-NGBO5Z5O.cjs.map} +1 -1
  28. package/dist/{chunk-SXVO2PXE.cjs → chunk-NRIJNBRG.cjs} +26 -26
  29. package/dist/{chunk-SXVO2PXE.cjs.map → chunk-NRIJNBRG.cjs.map} +1 -1
  30. package/dist/{chunk-WPMUNLCC.cjs → chunk-P5EN67AU.cjs} +59 -59
  31. package/dist/{chunk-WPMUNLCC.cjs.map → chunk-P5EN67AU.cjs.map} +1 -1
  32. package/dist/{chunk-B77THL7Y.cjs → chunk-PXTDEKAY.cjs} +7 -7
  33. package/dist/{chunk-B77THL7Y.cjs.map → chunk-PXTDEKAY.cjs.map} +1 -1
  34. package/dist/{chunk-CV3JHPLQ.cjs → chunk-WXNE2BF4.cjs} +37 -37
  35. package/dist/{chunk-CV3JHPLQ.cjs.map → chunk-WXNE2BF4.cjs.map} +1 -1
  36. package/dist/{chunk-6PTETC3Z.js → chunk-ZH2OEMQJ.js} +134 -157
  37. package/dist/{chunk-6PTETC3Z.js.map → chunk-ZH2OEMQJ.js.map} +1 -1
  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 +8 -4
  51. package/dist/components/features/auth/create-organization-form.d.ts.map +1 -1
  52. package/dist/components/features/auth/login-form.d.ts +18 -14
  53. package/dist/components/features/auth/login-form.d.ts.map +1 -1
  54. package/dist/components/features/auth/sso-providers.d.ts +7 -1
  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 +37 -28
  76. package/src/components/features/auth/login-form.tsx +29 -60
  77. package/src/components/features/auth/sso-providers.tsx +8 -1
  78. package/dist/chunk-7R3PASHE.cjs.map +0 -1
  79. /package/dist/{chunk-AHXDYVAE.js.map → chunk-2WXQFYNC.js.map} +0 -0
  80. /package/dist/{chunk-7E2DFRIK.js.map → chunk-32BSKGEI.js.map} +0 -0
  81. /package/dist/{chunk-ZAJPJ2JD.js.map → chunk-3OPSNUPJ.js.map} +0 -0
  82. /package/dist/{chunk-NBWZW22E.js.map → chunk-BMEA5NPX.js.map} +0 -0
  83. /package/dist/{chunk-KFXA4ZG3.js.map → chunk-DVYA3BDU.js.map} +0 -0
  84. /package/dist/{chunk-ZB57GGZX.js.map → chunk-E77Z2P3K.js.map} +0 -0
  85. /package/dist/{chunk-6CFMFNIB.js.map → chunk-FSOKLOXF.js.map} +0 -0
  86. /package/dist/{chunk-PAOY2AIG.js.map → chunk-GQHXJ37C.js.map} +0 -0
  87. /package/dist/{chunk-XWEECWZD.js.map → chunk-LYK6D7GU.js.map} +0 -0
  88. /package/dist/{chunk-A6KQMTJV.js.map → chunk-MWIYAVFT.js.map} +0 -0
  89. /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
- /** Primary submit ("Continue") */
16
- onSubmit: () => void
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 to offer. When non-empty the form switches to SSO mode:
31
- * the primary submit is replaced by a stack of provider buttons.
25
+ * SSO providers rendered below the email field. Always visible; gate
26
+ * clickability with `ssoDisabled` / `ssoEnabledProviders`.
32
27
  */
33
- ssoProviders?: AuthSsoProvider[]
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 submission. Covers the empty and SSO states from the
43
- * auth redesign: enter an email, then Continue or pick an SSO provider.
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 isSsoMode = !!ssoProviders && ssoProviders.length > 0
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
- {/* 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
- )}
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" />}