From a1fb1a1c7ce0d07004cb8141b3027ee40a179355 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Thu, 7 Aug 2025 10:53:50 -0600 Subject: [PATCH] Accessibility pass --- app/components/Button.js | 14 +++-- app/components/Header.js | 106 ++++++++++++++++++++-------------- app/components/HeaderTab.js | 2 +- app/components/HomeHeader.js | 79 ++++++++++++++++--------- app/components/Logo.js | 14 ++++- app/components/MenuBar.js | 7 ++- app/components/MenuBarItem.js | 58 ++++++++++++------- 7 files changed, 179 insertions(+), 101 deletions(-) diff --git a/app/components/Button.js b/app/components/Button.js index bfc3145..f120a79 100644 --- a/app/components/Button.js +++ b/app/components/Button.js @@ -36,9 +36,9 @@ export default function Button({ const variantStyles = { default: - "bg-[var(--color-surface-inverse-primary)] text-[var(--color-content-inverse-primary)] hover:bg-[var(--color-surface-inverse-primary)] hover:text-[var(--color-content-inverse-brand-primary)] hover:outline-[var(--border-color-default-brandprimary)] hover:outline-inset active:bg-[var(--color-surface-inverse-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:outline-[var(--border-color-default-brandprimary)] active:outline-offset-1 disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50", + "bg-[var(--color-surface-inverse-primary)] text-[var(--color-content-inverse-primary)] hover:bg-[var(--color-surface-inverse-primary)] hover:text-[var(--color-content-inverse-brand-primary)] hover:outline-[var(--border-color-default-brandprimary)] hover:outline-inset hover:scale-[1.02] hover:shadow-lg active:bg-[var(--color-surface-inverse-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:outline-[var(--border-color-default-brandprimary)] active:outline-offset-1 active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100 disabled:hover:shadow-none", secondary: - "bg-transparent text-[var(--color-content-default-brand-primary)] hover:text-[var(--color-content-default-primary)] focus:outline-1 focus:outline-inset focus:outline-[var(--border-color-default-tertiary)] focus:shadow-[0_0_10px_1px_#FFFDD2] focus:blur-[0px] active:outline-[1.5px] active:outline-inset active:outline-[var(--color-content-default-brand-primary)] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50", + "bg-transparent text-[var(--color-content-default-brand-primary)] hover:text-[var(--color-content-default-primary)] hover:scale-[1.02] hover:bg-[var(--color-surface-default-tertiary)] focus:outline-1 focus:outline-inset focus:outline-[var(--border-color-default-tertiary)] focus:shadow-[0_0_10px_1px_#FFFDD2] focus:blur-[0px] active:outline-[1.5px] active:outline-inset active:outline-[var(--color-content-default-brand-primary)] active:bg-[var(--color-surface-default-brand-primary)] active:text-[var(--color-content-inverse-primary)] active:scale-[0.98] disabled:bg-[var(--color-surface-default-secondary)] disabled:text-[var(--color-content-inverse-tertiary)] disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100 disabled:active:scale-100", }; const hoverOutlineStyles = { @@ -48,9 +48,10 @@ export default function Button({ xlarge: "hover:outline-[2.5px]", }; - const focusStyles = "focus:shadow-[0_0_10px_1px_#FFFDD2] focus:outline-none"; + const focusStyles = + "focus:shadow-[0_0_10px_1px_#FFFDD2] focus:outline-none focus:ring-1 focus:ring-[var(--color-content-default-brand-primary)] focus:ring-offset-1 focus:scale-[1.02]"; - const baseStyles = `inline-flex items-center justify-start box-border ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${fontStyles[size]} transition-all duration-200 cursor-pointer ${variantStyles[variant]} ${hoverOutlineStyles[size]} ${focusStyles}`; + const baseStyles = `inline-flex items-center justify-start box-border ${sizeStyles[size]} rounded-[var(--radius-measures-radius-full)] ${fontStyles[size]} transition-all duration-200 ease-in-out cursor-pointer ${variantStyles[variant]} ${hoverOutlineStyles[size]} ${focusStyles}`; let finalVariant = variant; if (disabled) { @@ -61,8 +62,11 @@ export default function Button({ const accessibilityProps = { ...(ariaLabel && { "aria-label": ariaLabel }), + ...(disabled && { "aria-disabled": "true" }), ...(target && { target }), ...(rel && { rel }), + tabIndex: disabled ? -1 : 0, + ...props, }; if (href && !disabled) { @@ -72,7 +76,6 @@ export default function Button({ className={combinedStyles} onClick={onClick} {...accessibilityProps} - {...props} > {children} @@ -86,7 +89,6 @@ export default function Button({ disabled={disabled} onClick={onClick} {...accessibilityProps} - {...props} > {children} diff --git a/app/components/Header.js b/app/components/Header.js index c32f8ff..0720f01 100644 --- a/app/components/Header.js +++ b/app/components/Header.js @@ -41,6 +41,7 @@ export default function Header({ onToggle }) { href={item.href} size={item.extraPadding && size === "xsmall" ? "xsmallUseCases" : size} onClick={onToggle} + ariaLabel={`Navigate to ${item.text} page`} > {item.text} @@ -62,22 +63,20 @@ export default function Header({ onToggle }) { ); }; - const renderLoginButton = (size, marginRight) => { + const renderLoginButton = (size) => { return ( - + Log in ); }; - const renderCreateRuleButton = ( - buttonSize, - containerSize, - avatarSize, - marginLeft - ) => { + const renderCreateRuleButton = (buttonSize, containerSize, avatarSize) => { return ( - @@ -89,9 +88,18 @@ export default function Header({ onToggle }) { }; return ( -
-
-
+
+
); } diff --git a/app/components/HeaderTab.js b/app/components/HeaderTab.js index 85da467..3c66b5d 100644 --- a/app/components/HeaderTab.js +++ b/app/components/HeaderTab.js @@ -1,7 +1,7 @@ export default function HeaderTab({ children, className = "", ...props }) { return (
{children} diff --git a/app/components/HomeHeader.js b/app/components/HomeHeader.js index da7dd72..a74a87e 100644 --- a/app/components/HomeHeader.js +++ b/app/components/HomeHeader.js @@ -82,6 +82,7 @@ export default function HomeHeader() { : "default" } onClick={() => setShowRegularHeader(!showRegularHeader)} + ariaLabel={`Navigate to ${item.text} page`} > {item.text} @@ -103,27 +104,26 @@ export default function HomeHeader() { ); }; - const renderLoginButton = (size, marginRight) => { + const renderLoginButton = (size) => { return ( Log in ); }; - const renderCreateRuleButton = ( - buttonSize, - containerSize, - avatarSize, - marginLeft - ) => { + const renderCreateRuleButton = (buttonSize, containerSize, avatarSize) => { return ( - @@ -139,9 +139,18 @@ export default function HomeHeader() { } return ( -
-
+
+
); } diff --git a/app/components/Logo.js b/app/components/Logo.js index 1355344..382ae0c 100644 --- a/app/components/Logo.js +++ b/app/components/Logo.js @@ -116,7 +116,9 @@ export default function Logo({ size = "default", showText = true }) {
{/* Logo Text - only show if showText is true */} {showText && ( @@ -129,7 +131,10 @@ export default function Logo({ size = "default", showText = true }) { size === "homeHeaderXl" ? "text-[var(--color-content-inverse-primary)]" : "text-[var(--color-content-default-primary)]" - } ${config.textSize} ${config.lineHeight} font-normal tracking-[0px]`} + } ${config.textSize} ${ + config.lineHeight + } font-normal tracking-[0px] transition-colors duration-200`} + aria-label="CommunityRule" > CommunityRule
@@ -141,7 +146,9 @@ export default function Logo({ size = "default", showText = true }) { alt="CommunityRule Logo Icon" width={27.05} height={27.05} - className={`flex-shrink-0 ${config.iconSize} ${ + className={`flex-shrink-0 ${ + config.iconSize + } transition-all duration-200 ${ size === "homeHeaderXsmall" || size === "homeHeaderSm" || size === "homeHeaderMd" || @@ -150,6 +157,7 @@ export default function Logo({ size = "default", showText = true }) { ? "filter brightness-0" : "" }`} + aria-hidden="true" />
); diff --git a/app/components/MenuBar.js b/app/components/MenuBar.js index e3188fc..275d6d3 100644 --- a/app/components/MenuBar.js +++ b/app/components/MenuBar.js @@ -18,7 +18,12 @@ export default function MenuBar({ const baseStyles = `flex items-center ${sizeStyles[size]} ${className}`; return ( -