Skip to content

Commit

Permalink
Merge pull request #157 from Myongji-Graduate/Accessibility-test/#136
Browse files Browse the repository at this point in the history
Accessibility test/#136
  • Loading branch information
seonghunYang authored Nov 30, 2024
2 parents 10a0543 + 1b2fbc4 commit 0d855d0
Show file tree
Hide file tree
Showing 22 changed files with 1,319 additions and 1,731 deletions.
1 change: 1 addition & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const config: StorybookConfig = {
'@storybook/addon-essentials',
'@storybook/addon-onboarding',
'@storybook/addon-interactions',
'@storybook/addon-a11y',
],
framework: {
name: '@storybook/nextjs',
Expand Down
32 changes: 32 additions & 0 deletions .storybook/test-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { TestRunnerConfig } from '@storybook/test-runner';
import { getStoryContext } from '@storybook/test-runner';

import { injectAxe, checkA11y, configureAxe } from 'axe-playwright';

/*
* See https://storybook.js.org/docs/writing-tests/test-runner#test-hook-api
* to learn more about the test-runner hooks API.
*/
const config: TestRunnerConfig = {
async preVisit(page) {
await injectAxe(page);
},
async postVisit(page, context) {
// Get the entire context of a story, including parameters, args, argTypes, etc.
const storyContext = await getStoryContext(page, context);

// Apply story-level a11y rules
await configureAxe(page, {
rules: storyContext.parameters?.a11y?.config?.rules,
});

await checkA11y(page, '#storybook-root', {
detailedReport: true,
detailedReportOptions: {
html: true,
},
});
},
};

export default config;
1 change: 0 additions & 1 deletion app/(sub-page)/sign-up/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import ContentContainer from '@/app/ui/view/atom/content-container/content-conta
import SignUpFormSkeleton from '@/app/ui/user/sign-up-form/sign-up-form.skeleton';
import type { Metadata } from 'next';


export const metadata: Metadata = {
title: '회원가입',
description: '졸업을 부탁해에 회원가입 하고 졸업요건을 간편하게 검사해 보세요.',
Expand Down
18 changes: 9 additions & 9 deletions app/ui/lecture/taken-lecture/delete-taken-lecture-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ export default function DeleteTakenLectureButton({ item, onDelete }: DeleteTaken
return (
<AlertDialog open={open} onOpenChange={setOpen}>
<AlertDialogTrigger asChild>
<div className="opacity-0 group-hover:opacity-100">
<Button
label="삭제"
variant="text"
size="default"
data-cy={`taken-lecture-delete-model-trigger-${item.id}`}
data-testid="taken-lecture-delete-button"
/>
</div>
<Button
label="삭제"
variant="text"
size="default"
tabIndex={open ? 0 : -1}
data-cy={`taken-lecture-delete-model-trigger-${item.id}`}
data-testid="taken-lecture-delete-button"
className="opacity-0 group-hover:opacity-100"
/>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
Expand Down
13 changes: 10 additions & 3 deletions app/ui/lecture/taken-lecture/taken-lecture-label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,30 @@ import useDialog from '@/app/hooks/useDialog';
import { DIALOG_KEY } from '@/app/utils/key/dialog-key.util';

export default function TakenLectureLabel() {
const { open } = useDialog(DIALOG_KEY.LECTURE_SEARCH);
const { isOpen, open } = useDialog(DIALOG_KEY.LECTURE_SEARCH);

return (
<LabelContainer
label="내 기이수 과목"
rightElement={
<div className="flex gap-2">
<Button
tabIndex={isOpen ? -1 : 0}
data-cy="open-lecture-search-dialog-button"
label="과목 추가"
variant="secondary"
size="xs"
data-testid="toggle-lecture-search"
onClick={open}
/>
<Link href="/grade-upload">
<Button className="max-lg:text-xs" label="성적표 재업로드" variant="secondary" size="xs" />
<Link tabIndex={isOpen ? -1 : 0} href="/grade-upload">
<Button
tabIndex={isOpen ? -1 : 0}
className="max-lg:text-xs"
label="성적표 재업로드"
variant="secondary"
size="xs"
/>
</Link>
</div>
}
Expand Down
4 changes: 2 additions & 2 deletions app/ui/result/result-category-card/result-category-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ const displaySeveralMajor = (category: ResultCategoryKey) => {
return (
<>
<Responsive maxWidth={767}>
<Button label={majorType} variant="outlined" size="xs" role="none presentation" className="p-1 text-[10px]" />
<Button label={majorType} variant="outlined" size="xs" as="div" className="p-1 text-[10px]" />
</Responsive>
<Responsive minWidth={768}>
<Button label={majorType} variant="outlined" size="xs" role="none presentation" />
<Button label={majorType} variant="outlined" size="xs" as="div" />
</Responsive>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function ResultCategoryDetailContent({
<div className={cn('flex justify-between mb-6', 'md:mb-10')}>
<div>
<h1 className={cn('text-2xl font-bold', 'md:text-4xl')}>{RESULT_CATEGORY_KO[category]}</h1>
<div className={cn('relative flex items-center gap-2 text-sm text-gray-6 font-medium my-2', 'md:text-lg')}>
<div className={cn('relative flex items-center gap-2 text-sm text-gray-7 font-medium my-2', 'md:text-lg')}>
<span className="hidden md:block"> {RESULT_CATEGORY_KO[category]} 과목 중</span>
<div className="w-20 h-10">
<ResultCategoryDetailLectureToggle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function ResultCagegoryDetailLecture({ detailCategory, isTakenLecture }: ResultC
<LabelContainer
label={categoryName}
rightElement={
<div className="text-2xl text-gray-6">
<div className="text-2xl text-gray-7">
{takenCredit} / {totalCredit}
</div>
}
Expand Down
4 changes: 2 additions & 2 deletions app/ui/view/atom/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/app/utils/shadcn/utils';

const alertVariants = cva(
'relative w-full rounded-lg border border-slate-200 px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-slate-950 [&>svg~*]:pl-7 dark:border-slate-800 dark:[&>svg]:text-slate-50',
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg]:translate-y-[3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
{
variants: {
variant: {
default: 'bg-white text-slate-950 dark:bg-slate-950 dark:text-slate-50',
destructive:
'border-red-500/50 text-red-500 dark:border-red-500 [&>svg]:text-red-500 dark:border-red-900/50 dark:text-red-900 dark:dark:border-red-900 dark:[&>svg]:text-red-900',
'border-etc-red/50 text-etc-red dark:border-etc-red [&>svg]:text-etc-red dark:border-red-900/50 dark:text-red-900 dark:dark:border-red-900 dark:[&>svg]:text-red-900',
},
},
defaultVariants: {
Expand Down
28 changes: 18 additions & 10 deletions app/ui/view/atom/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,20 @@ import LoadingSpinner from '../loading-spinner/loading-spinner';

export type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'default' | 'xl';

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
type ButtonProps<T extends React.ElementType> = {
as?: T;
label: string;
variant?: 'primary' | 'secondary' | 'text' | 'list' | 'outlined' | 'dark';
size?: ButtonSize;
loading?: boolean;
disabled?: boolean;
}
} & React.ComponentPropsWithoutRef<T>;

type ButtonComponent = <T extends React.ElementType = 'button'>(
props: ButtonProps<T> & {
ref?: React.ComponentPropsWithRef<T>['ref'];
},
) => React.ReactNode;

export const ButtonVariants = cva(`flex justify-center items-center`, {
variants: {
Expand All @@ -20,8 +27,8 @@ export const ButtonVariants = cva(`flex justify-center items-center`, {
outlined: 'rounded-[100px] text-primary border-solid border-[1px] border-primary',
dark: 'bg-dark rounded-[100px] text-white border-0 hover:bg-dark-hover',
secondary: 'bg-white rounded-[100px] border-solid border-[1px] border-gray-6 hover:bg-white-hover',
text: 'font-medium text-slate-400 text-sm hover:text-slate-600',
list: 'py-1 px-3 bg-blue-500 rounded-[7px] text-white leading-5 font-medium text-base hover:bg-blue-600',
text: 'font-medium text-slate-500 text-sm hover:text-slate-600',
list: 'py-1 px-3 bg-blue-600 rounded-[7px] text-white leading-5 font-medium text-base hover:bg-blue-700',
},
size: {
default: '',
Expand All @@ -47,24 +54,25 @@ export const LoadingIconVariants = cva('animate-spin shrink-0', {
},
});

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
{ className, label, variant = 'primary', size = 'default', loading, disabled, ...props },
ref,
const Button: ButtonComponent = React.forwardRef(function Button<T extends React.ElementType = 'button'>(
{ className, as, label, variant = 'primary', size = 'default', loading, disabled, ...props }: ButtonProps<T>,
ref: React.ComponentPropsWithRef<T>['ref'],
) {
const Element = as || 'button';
const isDisabled = loading || disabled;

return (
<button
<Element
className={cn(isDisabled && 'opacity-50 cursor-not-allowed', ButtonVariants({ variant, size }), className)}
disabled={disabled}
disabled={isDisabled}
{...props}
ref={ref}
>
{loading ? (
<LoadingSpinner className={cn(LoadingIconVariants({ size }))} style={{ transition: `width 150ms` }} />
) : null}
{label}
</button>
</Element>
);
});

Expand Down
2 changes: 1 addition & 1 deletion app/ui/view/atom/label-container/label-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface LabelContainerProps {
export default function LabelContainer({ label, rightElement }: LabelContainerProps) {
return (
<div className="flex justify-between items-center w-full">
<div className="rounded-[100px] bg-light-blue-6 p-2.5 text-white text-xs lg:text-sm xl:text-base 2xl:text-lg font-semibold">
<div className="rounded-[100px] bg-light-blue-9 p-2.5 text-white text-xs lg:text-sm xl:text-base 2xl:text-lg font-semibold">
{label}
</div>
{rightElement}
Expand Down
8 changes: 8 additions & 0 deletions app/ui/view/atom/text-input/text-input.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ const meta = {
title: 'ui/view/atom/TextInput',
component: TextInput,
tags: ['autodocs'],
decorators: [
(Story) => (
<label className="text-xs">
text-input
<Story />
</label>
),
],
argTypes: {
type: {
description: "Text Input의 type값으로 'text' | 'password' | 'number' 를 할당할 수 있습니다",
Expand Down
3 changes: 1 addition & 2 deletions app/ui/view/atom/text-input/text-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,10 @@ const TextInput = React.forwardRef<HTMLInputElement, TextInputProps>(function Te
type={type}
className={twMerge(
'w-full focus:outline-none focus:ring-0 border-none bg-transparent text-sm rounded-lg transition duration-100 py-2',
'text-black-1',
'[appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none',
Icon ? 'pl-2' : 'pl-3',
error ? 'pr-9' : 'pr-3',
disabled ? 'text-gray-6 placeholder:text-gray-6' : 'placeholder:text-gray-6',
disabled ? 'text-gray-8 placeholder:text-gray-6' : 'placeholder:text-gray-6 text-black-1',
)}
placeholder={placeholder}
disabled={disabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function AlertDestructive({ title, description }: AlertDestructiv
return (
<Alert variant="destructive">
<ExclamationTriangleIcon className="h-4 w-4" />
<AlertTitle>{title}</AlertTitle>
{title ? <AlertTitle>{title}</AlertTitle> : null}
<AlertDescription>{description}</AlertDescription>
</Alert>
);
Expand Down
1 change: 1 addition & 0 deletions app/ui/view/molecule/list/list-root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function ListRoot<T extends ListRow>({ data, render, isScrollList = false
isScrollList && 'h-72 overflow-auto',
hasNotData && 'flex justify-center items-center',
)}
tabIndex={isScrollList ? 0 : -1}
>
{data.map((item, index) => render && render(item, index))}
{hasNotData ? emptyDataRender() : null}
Expand Down
5 changes: 4 additions & 1 deletion app/ui/view/molecule/select/select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ const meta = {
decorators: [
(Story) => (
<div className="w-52">
<Story />
<label className="text-xs">
select:
<Story />
</label>
</div>
),
],
Expand Down
2 changes: 1 addition & 1 deletion app/ui/view/molecule/table/table-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface TableHeaderProps {

export function TableHeader({ cols, headerInfo }: TableHeaderProps) {
return (
<div className="text-light-blue-6 leading-4 text-sm xl:text-base 2xl:text-lg font-medium xl:font-semibold bg-light-blue-1 py-3 rounded-[100px]">
<div className="text-point-blue leading-4 text-sm xl:text-base 2xl:text-lg font-medium xl:font-semibold bg-light-blue-1 py-3 rounded-[100px]">
<Grid cols={cols}>
{headerInfo.map((info) => (
<Grid.Column key={info}>{info}</Grid.Column>
Expand Down
7 changes: 7 additions & 0 deletions app/ui/view/molecule/upload-pdf/upload-pdf.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ const meta = {
componentSubtitle:
'pdf를 click이나 drag&drop을 통해 업로드 할 수 있는 컴포넌트입니다. 파일을 등록한 경우에는 파일 명이 노출됩니다.',
},
decorators: [
(Story: any) => (
<label>
<Story />
</label>
),
],
} satisfies Meta<typeof UploadPdf>;

export default meta;
Expand Down
5 changes: 1 addition & 4 deletions app/ui/view/molecule/upload-pdf/upload-pdf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ function UploadPdf() {

return (
<div className="flex flex-col items-center gap-4">
<div
role="button"
className="relative p-2 m-auto w-96 flex flex-col justify-center items-center gap-2 border-dashed border-2 rounded-sm rounded-bl-xl border-light-blue-6 bg-light-blue-1 text-light-blue-6 max-lg:w-80"
>
<div className="relative p-2 m-auto w-96 flex flex-col justify-center items-center gap-2 border-dashed border-2 rounded-sm rounded-bl-xl border-light-blue-6 bg-light-blue-1 text-point-blue max-lg:w-80">
<Image src={file ? checkedBox : uploadBox} width={40} height={28} className="mx-auto" alt="upload-button" />
<span className="text-center break-keep whitespace-pre-line max-w-48 truncate">
{file ? file.name : '마우스로 드래그 하거나 아이콘을 눌러 추가해주세요.'}
Expand Down
Loading

0 comments on commit 0d855d0

Please sign in to comment.