Skip to content

chore(SidePanel): fix a11y contrast issue #3923

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 31, 2024
Merged
Changes from 2 commits
Commits
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
176 changes: 169 additions & 7 deletions packages/paste-core/components/side-panel/stories/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
import { Anchor } from "@twilio-paste/anchor";
import { Avatar } from "@twilio-paste/avatar";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion(non-blocking): probably best to keep these eslint-disables at the top of the file so eslint doesn't get angry about these 2 imports

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestion, addressed in latest PR

/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable react/jsx-max-depth */
/* eslint-disable import/no-extraneous-dependencies */
import { Box } from "@twilio-paste/box";
import { Button } from "@twilio-paste/button";
import { ChatComposer } from "@twilio-paste/chat-composer";
import { ChatBubble, ChatLog, ChatMessage, ChatMessageMeta, ChatMessageMetaItem } from "@twilio-paste/chat-log";
import { CustomizationProvider } from "@twilio-paste/customization";
import { DetailText } from "@twilio-paste/detail-text";
import { Heading } from "@twilio-paste/heading";
import { ArtificialIntelligenceIcon } from "@twilio-paste/icons/esm/ArtificialIntelligenceIcon";
import { ChevronDoubleLeftIcon } from "@twilio-paste/icons/esm/ChevronDoubleLeftIcon";
import { ChevronDoubleRightIcon } from "@twilio-paste/icons/esm/ChevronDoubleRightIcon";
import { MoreIcon } from "@twilio-paste/icons/esm/MoreIcon";
import { SidebarPushContentWrapper } from "@twilio-paste/sidebar";
import { useTheme } from "@twilio-paste/theme";
import { Topbar } from "@twilio-paste/topbar";
import { useUID } from "@twilio-paste/uid-library";
import * as React from "react";

import { Separator } from "@twilio-paste/separator";
import {
SidePanel,
SidePanelBody,
SidePanelButton,
SidePanelContainer,
SidePanelContext,
SidePanelHeader,
SidePanelHeaderActions,
SidePanelPushContentWrapper,
} from "../src";
} from "@twilio-paste/side-panel";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: why this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the other stories and they all used the same import format. I only now realize that is for all other components except the package it is changing. I will revert this

import { SidebarPushContentWrapper } from "@twilio-paste/sidebar";
import { useTheme } from "@twilio-paste/theme";
import { Topbar } from "@twilio-paste/topbar";
import { useUID } from "@twilio-paste/uid-library";
import * as React from "react";

import { MessagingInsightsContent } from "./components/MessagingInsightsContent";
import { SidePanelWithContent } from "./components/SidePanelWithContent";
import { SidebarWithContent } from "./components/SidebarWithContent";
Expand Down Expand Up @@ -52,6 +60,17 @@ export const Default = (): React.ReactNode => {
};
Default.parameters = {
padding: false,
a11y: {
config: {
rules: [
{
id: "color-contrast",
// Using position relative on SidePanel causes it to overflow other themes and fails color contrast checks VRT tests below enable this rule
enabled: false,
},
],
},
},
};

export const Basic = (): React.ReactNode => {
Expand All @@ -78,6 +97,17 @@ export const Basic = (): React.ReactNode => {
};
Basic.parameters = {
padding: false,
a11y: {
config: {
rules: [
{
id: "color-contrast",
// Using position relative on SidePanel causes it to overflow other themes and fails color contrast checks VRT tests below enable this rule
enabled: false,
},
],
},
},
};

export const I18n = (): React.ReactNode => {
Expand Down Expand Up @@ -127,6 +157,17 @@ export const I18n = (): React.ReactNode => {

I18n.parameters = {
padding: false,
a11y: {
config: {
rules: [
{
id: "color-contrast",
// Using position relative on SidePanel causes it to overflow other themes and fails color contrast checks VRT tests below enable this rule
enabled: false,
},
],
},
},
};

export const ContentDemo = (): React.ReactNode => {
Expand Down Expand Up @@ -195,6 +236,17 @@ export const ContentDemo = (): React.ReactNode => {

ContentDemo.parameters = {
padding: false,
a11y: {
config: {
rules: [
{
id: "color-contrast",
// Using position relative on SidePanel causes it to overflow other themes and fails color contrast checks VRT tests below enable this rule
enabled: false,
},
],
},
},
};

export const Composed = (): React.ReactNode => {
Expand Down Expand Up @@ -223,6 +275,17 @@ export const Composed = (): React.ReactNode => {

Composed.parameters = {
padding: false,
a11y: {
config: {
rules: [
{
id: "color-contrast",
// Using position relative on SidePanel causes it to overflow other themes and fails color contrast checks VRT tests below enable this rule
enabled: false,
},
],
},
},
};

export const Customized = (): React.ReactNode => {
Expand Down Expand Up @@ -279,4 +342,103 @@ export const Customized = (): React.ReactNode => {

Customized.parameters = {
padding: false,
a11y: {
config: {
rules: [
{
id: "color-contrast",
// Using position relative on SidePanel causes it to overflow other themes and fails color contrast checks VRT tests below enable this rule
enabled: false,
},
],
},
},
};

export const DefaultVRT = (): React.ReactNode => {
const sidePanelId = useUID();

return (
<SidePanelContext.Provider
value={{
i18nCloseSidePanelTitle: "close the side panel",
i18nOpenSidePanelTitle: "open the side panel",
isOpen: true,
setIsOpen: () => {},
sidePanelId,
}}
>
{/* close button in header needs an element to control */}
<Box id={sidePanelId} />
<SidePanelHeader>
<ArtificialIntelligenceIcon decorative size="sizeIcon50" color="colorTextIcon" />
<Heading as="h3" variant="heading30" marginBottom="space0">
Assistant
</Heading>
<SidePanelHeaderActions>
<Button variant="secondary_icon" size="reset" onClick={() => {}}>
<MoreIcon decorative={false} title="open menu" size="sizeIcon50" />
</Button>
</SidePanelHeaderActions>
</SidePanelHeader>
<Separator orientation="horizontal" verticalSpacing="space0" />
<SidePanelBody>
<Box width="100%">
<ChatLog>
<ChatMessage variant="inbound">
<ChatBubble>Hello, what can I help you with?</ChatBubble>
<ChatMessageMeta aria-label="said by Gibby Radki at 3:35 PM">
<ChatMessageMetaItem>
<Avatar name="Gibby Radki" size="sizeIcon20" />
Gibby Radki ・ 3:35 PM
</ChatMessageMetaItem>
</ChatMessageMeta>
</ChatMessage>
<ChatMessage variant="outbound">
<ChatBubble>Hi! What is your return policy?</ChatBubble>
<ChatMessageMeta aria-label="said by you at 3:35 PM">
<ChatMessageMetaItem>3:35 PM</ChatMessageMetaItem>
</ChatMessageMeta>
</ChatMessage>
<ChatMessage variant="inbound">
<ChatBubble>Hello, what can I help you with?</ChatBubble>
<ChatMessageMeta aria-label="said by Gibby Radki at 3:35 PM">
<ChatMessageMetaItem>
<Avatar name="Gibby Radki" size="sizeIcon20" />
Gibby Radki ・ 3:35 PM
</ChatMessageMetaItem>
</ChatMessageMeta>
</ChatMessage>
<ChatMessage variant="outbound">
<ChatBubble>Hi! What is your return policy?</ChatBubble>
<ChatMessageMeta aria-label="said by you at 3:35 PM">
<ChatMessageMetaItem>3:35 PM</ChatMessageMetaItem>
</ChatMessageMeta>
</ChatMessage>
</ChatLog>
<ChatComposer
config={{
namespace: "customer-chat",
onError: (e) => {
throw e;
},
}}
initialValue="Are switch labels required in the context of a data grid? I'm exploring a UI that allows users to make the same configuration to every row in that data grid, and i'm wondering if there are any accessibility issues with having the column header in the top row with just the switch component in each of the row cells? the label gets pretty repetitive and we're expecting the table to have 20+ rows in this table, so trying to find ways to make it less visually crowded"
placeholder="Chat text"
ariaLabel="A basic chat composer"
/>
<Box paddingX="space50" paddingTop="space30">
<DetailText>
This chatbot is powered by OpenAI. For more information, see the{" "}
<Anchor href="#">Customer AI Trust Principles</Anchor> and{" "}
<Anchor href="#">Twilio Privacy Notice.</Anchor>
</DetailText>
</Box>
</Box>
</SidePanelBody>
</SidePanelContext.Provider>
);
};
Default.parameters = {
padding: false,
};
Loading