('#chat-url')
+
+ expect(document.querySelector('[role="alert"]')).toBeNull()
+ expect(input?.getAttribute('aria-invalid')).toBe('false')
+ expect(input?.hasAttribute('aria-describedby')).toBe(false)
+ })
+})
diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/chat/chat.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/chat/chat.tsx
index b9dfb3271a2..3caefaad692 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/chat/chat.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/deploy/components/deploy-modal/components/chat/chat.tsx
@@ -1,6 +1,6 @@
'use client'
-import { useEffect, useRef, useState } from 'react'
+import { type ReactNode, useEffect, useId, useRef, useState } from 'react'
import {
ChipButtonGroup,
ChipButtonGroupItem,
@@ -49,6 +49,19 @@ const logger = createLogger('ChatDeploy')
const IDENTIFIER_PATTERN = /^[a-z0-9-]+$/
+interface DeployFieldErrorProps {
+ children: ReactNode
+ id?: string
+}
+
+function DeployFieldError({ children, id }: DeployFieldErrorProps) {
+ return (
+
+ {children}
+
+ )
+}
+
interface ChatDeployProps {
workflowId: string
deploymentInfo: {
@@ -382,11 +395,7 @@ export function ChatDeploy({
className='w-full'
disablePortal
/>
- {errors.outputBlocks && (
-
- {errors.outputBlocks}
-
- )}
+ {errors.outputBlocks && {errors.outputBlocks}}
@@ -539,7 +548,7 @@ const getDomainPrefix = (() => {
return () => prefix
})()
-function IdentifierInput({
+export function IdentifierInput({
value,
onChange,
originalIdentifier,
@@ -547,6 +556,7 @@ function IdentifierInput({
onValidationChange,
isEditingExisting = false,
}: IdentifierInputProps) {
+ const errorId = useId()
const { isChecking, error, isValid } = useIdentifierValidation(
value,
originalIdentifier,
@@ -590,6 +600,8 @@ function IdentifierInput({
onChange={(e) => handleChange(e.target.value)}
required
disabled={disabled}
+ aria-invalid={Boolean(error)}
+ aria-describedby={error ? errorId : undefined}
className={cn(
'rounded-none border-0 bg-transparent pl-0 shadow-none disabled:bg-transparent disabled:opacity-100',
(isChecking || (isValid && value)) && 'pr-8'
@@ -617,7 +629,7 @@ function IdentifierInput({
)}
- {error && {error}
}
+ {error && {error}}
{isEditingExisting && value ? (
<>
@@ -745,9 +757,7 @@ function AuthSelector({
}
/>
{canRevealPassword && revealPasswordMutation.isError && (
-
- Failed to load the current password
-
+ Failed to load the current password
)}
{getPasswordHelperText(hasExistingPassword)}
@@ -772,7 +782,7 @@ function AuthSelector({
)}
- {error &&
{error}
}
+ {error && {error}}
)
}