Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
5546b5f
feat: enhance accessibility and internationalization for AlertDisplay…
deon-sanchez Jul 9, 2026
5232c27
Merge branch 'release-1.11.0' into db-provider-a11y
deon-sanchez Jul 10, 2026
b06b578
Merge branch 'release-1.11.0' into db-provider-a11y
deon-sanchez Jul 13, 2026
9aee8ce
Merge branch 'release-1.11.0' into db-provider-a11y
deon-sanchez Jul 13, 2026
9a61719
Merge branch 'release-1.11.0' into db-provider-a11y
deon-sanchez Jul 13, 2026
fb34708
Merge branch 'release-1.11.0' into db-provider-a11y
deon-sanchez Jul 13, 2026
9b8f912
Merge branch 'release-1.11.0' of https://github.com/langflow-ai/langf…
deon-sanchez Jul 13, 2026
c8a0e86
Enhance Button Component Accessibility and Behavior
deon-sanchez Jul 13, 2026
82a79aa
fix(mcp): stabilize Tool Mode activation (#14188)
erichare Jul 21, 2026
034969b
Merge branch 'release-1.11.0' into db-provider-a11y
deon-sanchez Jul 21, 2026
9c55f8b
Merge branch 'release-1.12.0' into db-provider-a11y
deon-sanchez Jul 21, 2026
ba51545
Merge branch 'release-1.12.0' of https://github.com/langflow-ai/langf…
deon-sanchez Jul 21, 2026
3863c1a
[autofix.ci] apply automated fixes
autofix-ci[bot] Jul 21, 2026
88638a2
Merge branch 'release-1.12.0' into db-provider-a11y
deon-sanchez Jul 21, 2026
b2e85a7
Merge branch 'release-1.12.0' of https://github.com/langflow-ai/langf…
deon-sanchez Jul 22, 2026
e4a75c6
[autofix.ci] apply automated fixes
autofix-ci[bot] Jul 22, 2026
e6a6c42
Merge branch 'release-1.12.0' of https://github.com/langflow-ai/langf…
deon-sanchez Jul 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ describe("AlertDisplayArea accessibility", () => {
it("keeps_live_regions_mounted_before_alerts_are_inserted", () => {
const { container } = render(<AlertDisplayArea />);

expect(
screen.getByRole("region", { name: "Notifications" }),
).toBeInTheDocument();
expect(
container.querySelector('[aria-live="assertive"]'),
).toBeInTheDocument();
Expand All @@ -48,7 +51,9 @@ describe("AlertDisplayArea accessibility", () => {
useAlertStore.getState().setSuccessData({ title: "Flow saved" });
});

const region = screen.getByRole("region", { name: "Notifications" });
const status = screen.getByRole("status");
expect(region).toContainElement(status);
expect(status).toHaveAttribute("aria-live", "polite");
expect(status).toHaveAttribute("aria-atomic", "true");
expect(status).toHaveTextContent("Flow saved");
Expand Down
8 changes: 7 additions & 1 deletion src/frontend/src/alerts/displayArea/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useTranslation } from "react-i18next";
import useAlertStore from "../../stores/alertStore";
import ErrorAlert from "../error";
import NoticeAlert from "../notice";
import SuccessAlert from "../success";

export default function AlertDisplayArea() {
const { t } = useTranslation();
const removeFromTempNotificationList = useAlertStore(
(state) => state.removeFromTempNotificationList,
);
Expand All @@ -21,7 +23,11 @@ export default function AlertDisplayArea() {
);

return (
<div style={{ zIndex: 999 }}>
<div
role="region"
aria-label={t("alerts.notificationsTitle")}
style={{ zIndex: 999 }}
>
<div
aria-atomic="true"
aria-live="assertive"
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/src/components/ui/__tests__/button.a11y.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ describe("Button accessibility", () => {
});

it("should_keep_accessible_name_while_loading", () => {
// Loading visually hides the label ("invisible" class) but must keep
// it in the accessibility tree so the name does not disappear.
// Loading keeps the label via sr-only (visibility:hidden would drop the name).
render(<Button loading>Save flow</Button>);

const button = screen.getByRole("button", { name: "Save Flow" });
expect(button).toBeDisabled();
expect(button).toHaveAttribute("aria-busy", "true");
});

it("should_be_disabled_when_disabled", () => {
Expand Down
4 changes: 4 additions & 0 deletions src/frontend/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,20 +106,24 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
: cn(className)
}
disabled={loading || disabled}
aria-busy={loading || undefined}
{...(asChild ? {} : { type: type || "button" })}
ref={ref}
{...props}
>
{loading ? (
<span className="relative flex items-center justify-center">
{/* Reserve layout width; hide from a11y so the name comes from sr-only. */}
<span
aria-hidden="true"
className={cn(
className,
"invisible flex items-center justify-center gap-2 !p-0",
)}
>
{newChildren}
</span>
<span className="sr-only">{newChildren}</span>
<span className="absolute inset-0 flex items-center justify-center">
<ForwardedIconComponent
name={"Loader2"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ function ProviderListItem({
className={cn(
"flex w-full cursor-pointer items-center justify-between rounded-lg px-2 py-3 text-left transition-colors hover:bg-muted/50",
isSelected && "bg-muted/50",
isComingSoon && "cursor-default opacity-70",
isComingSoon && "cursor-default",
)}
onClick={onSelect}
>
Expand All @@ -553,7 +553,7 @@ function ProviderListItem({
{provider.label}
</span>
{isComingSoon && (
<Badge variant="secondaryStatic" size="sq" className="text-xs">
<Badge variant="secondary" size="sq" className="text-xs">
{t("settings.dbProviders.comingSoon")}
</Badge>
)}
Expand Down Expand Up @@ -644,7 +644,7 @@ function ProviderConfigurationPanel({
</Badge>
)}
{isComingSoon && (
<Badge variant="secondaryStatic" size="sq" className="text-xs">
<Badge variant="secondary" size="sq" className="text-xs">
{t("settings.dbProviders.comingSoon")}
</Badge>
)}
Expand Down
Loading
Loading