@flamingo-stack/openframe-frontend-core 0.0.399 → 0.0.400
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-4K5XJ5EJ.js → chunk-463X3AW2.js} +3 -3
- package/dist/{chunk-XBCAY6NE.js → chunk-4HAVKWTJ.js} +3 -3
- package/dist/{chunk-G5NDKTX6.cjs → chunk-556BG7SX.cjs} +40 -40
- package/dist/{chunk-G5NDKTX6.cjs.map → chunk-556BG7SX.cjs.map} +1 -1
- package/dist/{chunk-2L6ALD2Q.js → chunk-56XCRZ7I.js} +2 -2
- package/dist/{chunk-BSJO5VFV.js → chunk-6VR7BJF6.js} +5 -5
- package/dist/{chunk-VOHOA3WV.cjs → chunk-6XQJSN7G.cjs} +15 -15
- package/dist/{chunk-VOHOA3WV.cjs.map → chunk-6XQJSN7G.cjs.map} +1 -1
- package/dist/{chunk-QNYNXSYQ.cjs → chunk-ABRDOCVN.cjs} +7 -7
- package/dist/{chunk-QNYNXSYQ.cjs.map → chunk-ABRDOCVN.cjs.map} +1 -1
- package/dist/{chunk-ZSZRJWY3.js → chunk-DH6HTYOV.js} +153 -134
- package/dist/chunk-DH6HTYOV.js.map +1 -0
- package/dist/{chunk-YWCCKB4J.cjs → chunk-EFTKJFEF.cjs} +5 -5
- package/dist/{chunk-YWCCKB4J.cjs.map → chunk-EFTKJFEF.cjs.map} +1 -1
- package/dist/{chunk-G3A7QHCX.js → chunk-FHEIG7QO.js} +2 -2
- package/dist/{chunk-Z5ERSGP2.js → chunk-I4XG5PJA.js} +2 -2
- package/dist/{chunk-D5IHYUBY.cjs → chunk-ILWSJCWD.cjs} +29 -29
- package/dist/{chunk-D5IHYUBY.cjs.map → chunk-ILWSJCWD.cjs.map} +1 -1
- package/dist/{chunk-JWBRDNYH.cjs → chunk-J4XR6YYZ.cjs} +23 -4
- package/dist/chunk-J4XR6YYZ.cjs.map +1 -0
- package/dist/{chunk-7OKNKZBW.cjs → chunk-J6IQQJJQ.cjs} +566 -531
- package/dist/chunk-J6IQQJJQ.cjs.map +1 -0
- package/dist/{chunk-O5NA3ULU.cjs → chunk-KIC4ZEZ7.cjs} +73 -73
- package/dist/{chunk-O5NA3ULU.cjs.map → chunk-KIC4ZEZ7.cjs.map} +1 -1
- package/dist/{chunk-VVKWNVKE.js → chunk-LAL63W5J.js} +6 -6
- package/dist/{chunk-JBLBFJ4N.cjs → chunk-MFRP2UDK.cjs} +32 -32
- package/dist/{chunk-JBLBFJ4N.cjs.map → chunk-MFRP2UDK.cjs.map} +1 -1
- package/dist/{chunk-A6KGHQRF.js → chunk-MQRTT3DO.js} +6 -6
- package/dist/{chunk-4KWIQEZT.js → chunk-MTBFE3JF.js} +2 -2
- package/dist/{chunk-RIC4TCPD.cjs → chunk-OPD5V57R.cjs} +19 -19
- package/dist/{chunk-RIC4TCPD.cjs.map → chunk-OPD5V57R.cjs.map} +1 -1
- package/dist/{chunk-CRRH7RJX.js → chunk-PD5MXNTJ.js} +5 -5
- package/dist/{chunk-WBLRUO3F.cjs → chunk-Q3AO2QWK.cjs} +3 -3
- package/dist/{chunk-WBLRUO3F.cjs.map → chunk-Q3AO2QWK.cjs.map} +1 -1
- package/dist/{chunk-4PEC5KU6.cjs → chunk-QGQ76SSR.cjs} +12 -12
- package/dist/{chunk-4PEC5KU6.cjs.map → chunk-QGQ76SSR.cjs.map} +1 -1
- package/dist/{chunk-ZDT2MBKE.cjs → chunk-RSFHAFZN.cjs} +40 -40
- package/dist/{chunk-ZDT2MBKE.cjs.map → chunk-RSFHAFZN.cjs.map} +1 -1
- package/dist/{chunk-4H2ICJYB.js → chunk-RYPCNUXA.js} +4 -4
- package/dist/{chunk-FXWURWDU.js → chunk-UFP45JLE.js} +3 -3
- package/dist/{chunk-2XVOYDRF.js → chunk-UYBNOHTC.js} +57 -22
- package/dist/{chunk-2XVOYDRF.js.map → chunk-UYBNOHTC.js.map} +1 -1
- package/dist/{chunk-NCW22SII.cjs → chunk-VTSEL7CJ.cjs} +73 -73
- package/dist/{chunk-NCW22SII.cjs.map → chunk-VTSEL7CJ.cjs.map} +1 -1
- package/dist/components/case-studies/index.cjs +9 -9
- package/dist/components/case-studies/index.js +3 -3
- package/dist/components/chat/index.cjs +3 -3
- package/dist/components/chat/index.js +2 -2
- package/dist/components/contact/index.cjs +4 -4
- package/dist/components/contact/index.js +3 -3
- package/dist/components/docs/index.cjs +6 -6
- package/dist/components/docs/index.js +5 -5
- package/dist/components/embeds/index.cjs +4 -4
- package/dist/components/embeds/index.js +3 -3
- package/dist/components/faq/index.cjs +5 -5
- package/dist/components/faq/index.js +4 -4
- package/dist/components/features/auth/auth-benefits-panel.d.ts.map +1 -1
- package/dist/components/features/auth/complete-account-form.d.ts.map +1 -1
- package/dist/components/features/auth/create-organization-form.d.ts.map +1 -1
- package/dist/components/features/auth/login-form.d.ts.map +1 -1
- package/dist/components/features/auth/openframe-sso-login-form.d.ts.map +1 -1
- package/dist/components/features/auth/openframe-sso-signup-form.d.ts.map +1 -1
- package/dist/components/features/auth/password-reset-form.d.ts.map +1 -1
- package/dist/components/features/index.cjs +3 -3
- package/dist/components/features/index.js +2 -2
- package/dist/components/help-center-pages/index.cjs +22 -22
- package/dist/components/help-center-pages/index.js +13 -13
- package/dist/components/index.cjs +125 -125
- package/dist/components/index.js +11 -11
- package/dist/components/navigation/index.cjs +3 -3
- package/dist/components/navigation/index.js +2 -2
- package/dist/components/onboarding-guides/index.cjs +7 -7
- package/dist/components/onboarding-guides/index.js +6 -6
- package/dist/components/related-content/index.cjs +5 -5
- package/dist/components/related-content/index.js +4 -4
- package/dist/components/tickets/index.cjs +6 -6
- package/dist/components/tickets/index.js +5 -5
- package/dist/components/ui/index.cjs +3 -3
- package/dist/components/ui/index.js +2 -2
- package/dist/hooks/index.cjs +4 -2
- package/dist/hooks/index.cjs.map +1 -1
- package/dist/hooks/index.js +3 -1
- package/dist/hooks/ui/index.d.ts +1 -0
- package/dist/hooks/ui/index.d.ts.map +1 -1
- package/dist/hooks/ui/use-deferred-error.d.ts +16 -0
- package/dist/hooks/ui/use-deferred-error.d.ts.map +1 -0
- package/dist/index.cjs +5 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -2
- package/package.json +1 -1
- package/src/components/features/auth/auth-benefits-panel.tsx +1 -1
- package/src/components/features/auth/complete-account-form.tsx +15 -4
- package/src/components/features/auth/create-organization-form.tsx +14 -5
- package/src/components/features/auth/login-form.tsx +6 -1
- package/src/components/features/auth/openframe-sso-login-form.tsx +9 -2
- package/src/components/features/auth/openframe-sso-signup-form.tsx +18 -5
- package/src/components/features/auth/password-reset-form.tsx +9 -2
- package/src/hooks/ui/index.ts +1 -0
- package/src/hooks/ui/use-deferred-error.ts +38 -0
- package/src/stories/Input.stories.tsx +1 -1
- package/src/stories/auth/CreateOrganization.stories.tsx +2 -1
- package/dist/chunk-7OKNKZBW.cjs.map +0 -1
- package/dist/chunk-JWBRDNYH.cjs.map +0 -1
- package/dist/chunk-ZSZRJWY3.js.map +0 -1
- /package/dist/{chunk-4K5XJ5EJ.js.map → chunk-463X3AW2.js.map} +0 -0
- /package/dist/{chunk-XBCAY6NE.js.map → chunk-4HAVKWTJ.js.map} +0 -0
- /package/dist/{chunk-2L6ALD2Q.js.map → chunk-56XCRZ7I.js.map} +0 -0
- /package/dist/{chunk-BSJO5VFV.js.map → chunk-6VR7BJF6.js.map} +0 -0
- /package/dist/{chunk-G3A7QHCX.js.map → chunk-FHEIG7QO.js.map} +0 -0
- /package/dist/{chunk-Z5ERSGP2.js.map → chunk-I4XG5PJA.js.map} +0 -0
- /package/dist/{chunk-VVKWNVKE.js.map → chunk-LAL63W5J.js.map} +0 -0
- /package/dist/{chunk-A6KGHQRF.js.map → chunk-MQRTT3DO.js.map} +0 -0
- /package/dist/{chunk-4KWIQEZT.js.map → chunk-MTBFE3JF.js.map} +0 -0
- /package/dist/{chunk-CRRH7RJX.js.map → chunk-PD5MXNTJ.js.map} +0 -0
- /package/dist/{chunk-4H2ICJYB.js.map → chunk-RYPCNUXA.js.map} +0 -0
- /package/dist/{chunk-FXWURWDU.js.map → chunk-UFP45JLE.js.map} +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type * as React from 'react'
|
|
4
4
|
import { cn } from '../../../utils/cn'
|
|
5
|
+
import { useDeferredError } from '../../../hooks/ui/use-deferred-error'
|
|
5
6
|
import { Button } from '../../ui/button'
|
|
6
7
|
import { Input } from '../../ui/input'
|
|
7
8
|
import type { AuthSsoProvider } from './sso-providers'
|
|
@@ -61,6 +62,9 @@ export function LoginForm({
|
|
|
61
62
|
const isSsoMode = !!ssoProviders && ssoProviders.length > 0
|
|
62
63
|
const fieldDisabled = disabled || loading || isSsoMode
|
|
63
64
|
|
|
65
|
+
// Validation messages are deferred while the user is typing (shown on blur or after a pause).
|
|
66
|
+
const emailErr = useDeferredError(errors?.email, email)
|
|
67
|
+
|
|
64
68
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
65
69
|
if (event.key === 'Enter' && !fieldDisabled) {
|
|
66
70
|
onSubmit()
|
|
@@ -86,8 +90,9 @@ export function LoginForm({
|
|
|
86
90
|
label="Email"
|
|
87
91
|
placeholder={emailPlaceholder}
|
|
88
92
|
value={email}
|
|
89
|
-
error={
|
|
93
|
+
error={emailErr.error}
|
|
90
94
|
disabled={fieldDisabled}
|
|
95
|
+
onBlur={emailErr.onBlur}
|
|
91
96
|
onChange={(event) => onEmailChange(event.target.value)}
|
|
92
97
|
onKeyDown={handleKeyDown}
|
|
93
98
|
/>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type * as React from 'react'
|
|
4
4
|
import { cn } from '../../../utils/cn'
|
|
5
|
+
import { useDeferredError } from '../../../hooks/ui/use-deferred-error'
|
|
5
6
|
import { Button } from '../../ui/button'
|
|
6
7
|
import { Input } from '../../ui/input'
|
|
7
8
|
import { PasswordInput } from '../../ui/password-input'
|
|
@@ -60,6 +61,10 @@ export function OpenFrameSsoLoginForm({
|
|
|
60
61
|
}: OpenFrameSsoLoginFormProps) {
|
|
61
62
|
const fieldsDisabled = disabled || loading
|
|
62
63
|
|
|
64
|
+
// Validation messages are deferred while the user is typing (shown on blur or after a pause).
|
|
65
|
+
const emailErr = useDeferredError(errors?.email, email)
|
|
66
|
+
const passwordErr = useDeferredError(errors?.password, password)
|
|
67
|
+
|
|
63
68
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
64
69
|
if (event.key === 'Enter' && !fieldsDisabled && !submitDisabled) {
|
|
65
70
|
onSubmit()
|
|
@@ -84,8 +89,9 @@ export function OpenFrameSsoLoginForm({
|
|
|
84
89
|
label={emailLabel}
|
|
85
90
|
placeholder={emailPlaceholder}
|
|
86
91
|
value={email}
|
|
87
|
-
error={
|
|
92
|
+
error={emailErr.error}
|
|
88
93
|
disabled={fieldsDisabled}
|
|
94
|
+
onBlur={emailErr.onBlur}
|
|
89
95
|
onChange={(event) => onEmailChange(event.target.value)}
|
|
90
96
|
onKeyDown={handleKeyDown}
|
|
91
97
|
/>
|
|
@@ -94,8 +100,9 @@ export function OpenFrameSsoLoginForm({
|
|
|
94
100
|
label={passwordLabel}
|
|
95
101
|
placeholder={passwordPlaceholder}
|
|
96
102
|
value={password}
|
|
97
|
-
error={
|
|
103
|
+
error={passwordErr.error}
|
|
98
104
|
disabled={fieldsDisabled}
|
|
105
|
+
onBlur={passwordErr.onBlur}
|
|
99
106
|
onChange={(event) => onPasswordChange(event.target.value)}
|
|
100
107
|
onKeyDown={handleKeyDown}
|
|
101
108
|
/>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type * as React from 'react'
|
|
4
4
|
import { cn } from '../../../utils/cn'
|
|
5
|
+
import { useDeferredError } from '../../../hooks/ui/use-deferred-error'
|
|
5
6
|
import { Button } from '../../ui/button'
|
|
6
7
|
import { Input } from '../../ui/input'
|
|
7
8
|
import { PasswordInput } from '../../ui/password-input'
|
|
@@ -72,6 +73,13 @@ export function OpenFrameSsoSignUpForm({
|
|
|
72
73
|
}: OpenFrameSsoSignUpFormProps) {
|
|
73
74
|
const fieldsDisabled = disabled || loading
|
|
74
75
|
|
|
76
|
+
// Validation messages are deferred while the user is typing (shown on blur or after a pause).
|
|
77
|
+
const emailErr = useDeferredError(errors?.email, email)
|
|
78
|
+
const firstNameErr = useDeferredError(errors?.firstName, firstName)
|
|
79
|
+
const lastNameErr = useDeferredError(errors?.lastName, lastName)
|
|
80
|
+
const passwordErr = useDeferredError(errors?.password, password)
|
|
81
|
+
const confirmErr = useDeferredError(errors?.confirmPassword, confirmPassword)
|
|
82
|
+
|
|
75
83
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
76
84
|
if (event.key === 'Enter' && !fieldsDisabled && !submitDisabled) {
|
|
77
85
|
onSubmit()
|
|
@@ -96,8 +104,9 @@ export function OpenFrameSsoSignUpForm({
|
|
|
96
104
|
label={emailLabel}
|
|
97
105
|
placeholder="username@mail.com"
|
|
98
106
|
value={email}
|
|
99
|
-
error={
|
|
107
|
+
error={emailErr.error}
|
|
100
108
|
disabled={fieldsDisabled || emailReadOnly}
|
|
109
|
+
onBlur={emailErr.onBlur}
|
|
101
110
|
onChange={(event) => onEmailChange(event.target.value)}
|
|
102
111
|
onKeyDown={handleKeyDown}
|
|
103
112
|
/>
|
|
@@ -107,8 +116,9 @@ export function OpenFrameSsoSignUpForm({
|
|
|
107
116
|
label="First Name"
|
|
108
117
|
placeholder="Enter First Name"
|
|
109
118
|
value={firstName}
|
|
110
|
-
error={
|
|
119
|
+
error={firstNameErr.error}
|
|
111
120
|
disabled={fieldsDisabled}
|
|
121
|
+
onBlur={firstNameErr.onBlur}
|
|
112
122
|
onChange={(event) => onFirstNameChange(event.target.value)}
|
|
113
123
|
onKeyDown={handleKeyDown}
|
|
114
124
|
/>
|
|
@@ -116,8 +126,9 @@ export function OpenFrameSsoSignUpForm({
|
|
|
116
126
|
label="Last Name"
|
|
117
127
|
placeholder="Enter Last Name"
|
|
118
128
|
value={lastName}
|
|
119
|
-
error={
|
|
129
|
+
error={lastNameErr.error}
|
|
120
130
|
disabled={fieldsDisabled}
|
|
131
|
+
onBlur={lastNameErr.onBlur}
|
|
121
132
|
onChange={(event) => onLastNameChange(event.target.value)}
|
|
122
133
|
onKeyDown={handleKeyDown}
|
|
123
134
|
/>
|
|
@@ -125,8 +136,9 @@ export function OpenFrameSsoSignUpForm({
|
|
|
125
136
|
label="Password"
|
|
126
137
|
placeholder="Enter Password"
|
|
127
138
|
value={password}
|
|
128
|
-
error={
|
|
139
|
+
error={passwordErr.error}
|
|
129
140
|
disabled={fieldsDisabled}
|
|
141
|
+
onBlur={passwordErr.onBlur}
|
|
130
142
|
onChange={(event) => onPasswordChange(event.target.value)}
|
|
131
143
|
onKeyDown={handleKeyDown}
|
|
132
144
|
/>
|
|
@@ -134,8 +146,9 @@ export function OpenFrameSsoSignUpForm({
|
|
|
134
146
|
label="Confirm Password"
|
|
135
147
|
placeholder="Confirm Password"
|
|
136
148
|
value={confirmPassword}
|
|
137
|
-
error={
|
|
149
|
+
error={confirmErr.error}
|
|
138
150
|
disabled={fieldsDisabled}
|
|
151
|
+
onBlur={confirmErr.onBlur}
|
|
139
152
|
onChange={(event) => onConfirmPasswordChange(event.target.value)}
|
|
140
153
|
onKeyDown={handleKeyDown}
|
|
141
154
|
/>
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import type * as React from 'react'
|
|
4
4
|
import { cn } from '../../../utils/cn'
|
|
5
|
+
import { useDeferredError } from '../../../hooks/ui/use-deferred-error'
|
|
5
6
|
import { Button } from '../../ui/button'
|
|
6
7
|
import { Input } from '../../ui/input'
|
|
7
8
|
import { BackToLoginLink } from './back-to-login-link'
|
|
@@ -66,6 +67,10 @@ export function PasswordResetForm({
|
|
|
66
67
|
}: PasswordResetFormProps) {
|
|
67
68
|
const fieldsDisabled = disabled || loading
|
|
68
69
|
|
|
70
|
+
// Validation messages are deferred while the user is typing (shown on blur or after a pause).
|
|
71
|
+
const passwordErr = useDeferredError(errors?.password, password)
|
|
72
|
+
const confirmErr = useDeferredError(errors?.confirmPassword, confirmPassword)
|
|
73
|
+
|
|
69
74
|
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
70
75
|
if (event.key === 'Enter' && !fieldsDisabled && !submitDisabled) {
|
|
71
76
|
onSubmit()
|
|
@@ -91,8 +96,9 @@ export function PasswordResetForm({
|
|
|
91
96
|
label={newPasswordLabel}
|
|
92
97
|
placeholder={newPasswordPlaceholder}
|
|
93
98
|
value={password}
|
|
94
|
-
error={
|
|
99
|
+
error={passwordErr.error}
|
|
95
100
|
disabled={fieldsDisabled}
|
|
101
|
+
onBlur={passwordErr.onBlur}
|
|
96
102
|
onChange={(event) => onPasswordChange(event.target.value)}
|
|
97
103
|
onKeyDown={handleKeyDown}
|
|
98
104
|
/>
|
|
@@ -103,8 +109,9 @@ export function PasswordResetForm({
|
|
|
103
109
|
label={confirmPasswordLabel}
|
|
104
110
|
placeholder={confirmPasswordPlaceholder}
|
|
105
111
|
value={confirmPassword}
|
|
106
|
-
error={
|
|
112
|
+
error={confirmErr.error}
|
|
107
113
|
disabled={fieldsDisabled}
|
|
114
|
+
onBlur={confirmErr.onBlur}
|
|
108
115
|
onChange={(event) => onConfirmPasswordChange(event.target.value)}
|
|
109
116
|
onKeyDown={handleKeyDown}
|
|
110
117
|
/>
|
package/src/hooks/ui/index.ts
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
|
|
5
|
+
export interface UseDeferredErrorResult {
|
|
6
|
+
/** The message to render (undefined while the reveal is deferred or the field is valid). */
|
|
7
|
+
error: string | undefined
|
|
8
|
+
/** Attach to the field's onBlur — reveals validation immediately and keeps it live from then on. */
|
|
9
|
+
onBlur: () => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Defers showing a field validation message while the user is still typing.
|
|
14
|
+
*
|
|
15
|
+
* The message is revealed when the field loses focus (touched) or when the
|
|
16
|
+
* value hasn't changed for `delay` ms; every keystroke restarts the timer.
|
|
17
|
+
* Once touched, validation stays live. A message that clears (the value became
|
|
18
|
+
* valid) disappears immediately.
|
|
19
|
+
*/
|
|
20
|
+
export function useDeferredError(error: string | undefined, value: string, delay = 1500): UseDeferredErrorResult {
|
|
21
|
+
const [touched, setTouched] = React.useState(false)
|
|
22
|
+
const [paused, setPaused] = React.useState(false)
|
|
23
|
+
|
|
24
|
+
// Typing hides the message and restarts the pause timer.
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
if (touched) return
|
|
27
|
+
setPaused(false)
|
|
28
|
+
const timer = setTimeout(() => setPaused(true), delay)
|
|
29
|
+
return () => clearTimeout(timer)
|
|
30
|
+
}, [value, delay, touched])
|
|
31
|
+
|
|
32
|
+
const onBlur = React.useCallback(() => setTouched(true), [])
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
error: error && (touched || paused) ? error : undefined,
|
|
36
|
+
onBlur,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -99,12 +99,13 @@ export const Filled: Story = {
|
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
101
|
* Error state: long messages under the fields wrap up to two lines.
|
|
102
|
+
* Validation is deferred — messages appear after a 1.5s typing pause or on blur.
|
|
102
103
|
*/
|
|
103
104
|
export const ErrorState: Story = {
|
|
104
105
|
render: () => (
|
|
105
106
|
<CreateOrganizationPage
|
|
106
107
|
email="ada@example.com"
|
|
107
|
-
organizationName="
|
|
108
|
+
organizationName="A"
|
|
108
109
|
domainSuffix=".openframe.ai"
|
|
109
110
|
termsUrl="#terms"
|
|
110
111
|
privacyPolicyUrl="#privacy"
|