카테고리 접근성 적용

This commit is contained in:
junghoon86.park
2024-05-31 14:05:02 +09:00
parent 7ddfcc2947
commit a2616b0cb8
9 changed files with 75 additions and 47 deletions

View File

@@ -5,9 +5,9 @@ import classNames from "classnames";
import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator"; import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
import useScrollReset from "../../hooks/useScrollReset"; import useScrollReset from "../../hooks/useScrollReset";
import { $L } from "../../utils/helperMethods";
import css from "./TButtonTab.module.less"; import css from "./TButtonTab.module.less";
import TButtonTabItem from "./TButtonTabItem"; import TButtonTabItem from "./TButtonTabItem";
import { $L } from "../../utils/helperMethods";
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused" }, { enterTo: "last-focused" },
@@ -66,6 +66,21 @@ export default function TButtonTab({
{...rest} {...rest}
> >
{contents.map((item, index) => { {contents.map((item, index) => {
const selectedText = "Selected, ";
let ariaLabelText = null;
const selectedChk = index === selectedIndex;
if (selectedChk) {
ariaLabelText =
selectedText +
item +
", tab, " +
(index * 1 + 1) +
" of " +
contents.length;
} else {
ariaLabelText =
item + ", tab, " + (index * 1 + 1) + " of " + contents.length;
}
return ( return (
<TButtonTabItem <TButtonTabItem
key={`buttonTabItem ${index}`} key={`buttonTabItem ${index}`}
@@ -79,6 +94,7 @@ export default function TButtonTab({
colorType={colorType} colorType={colorType}
onFocus={handleScrollReset} onFocus={handleScrollReset}
onBlur={handleStopScrolling} onBlur={handleStopScrolling}
ariaLabel={ariaLabelText}
> >
{$L(item)} {$L(item)}
</TButtonTabItem> </TButtonTabItem>

View File

@@ -28,6 +28,7 @@ const ItemBase = ({
scrollTop, scrollTop,
onBlur, onBlur,
onFocus, onFocus,
ariaLabel,
...rest ...rest
}) => { }) => {
const [pressed, setPressed] = useState(false); const [pressed, setPressed] = useState(false);
@@ -88,6 +89,7 @@ const ItemBase = ({
spotlightDisabled={spotlightDisabled} spotlightDisabled={spotlightDisabled}
onFocus={_onFocus} onFocus={_onFocus}
onBlur={_onBlur} onBlur={_onBlur}
aria-label={ariaLabel}
> >
{noMarquee ? ( {noMarquee ? (
<div className={css.title}>{convertNewlinesToBr(children)}</div> <div className={css.title}>{convertNewlinesToBr(children)}</div>

View File

@@ -45,6 +45,7 @@ export default function TDropDown({
onBlur={handleStopScrolling} onBlur={handleStopScrolling}
onOpen={_onOpen} onOpen={_onOpen}
onClose={_onClose} onClose={_onClose}
aria-label={children}
{...rest} {...rest}
> >
{children} {children}

View File

@@ -62,7 +62,6 @@ export default function ItemContents({ onClick }) {
prdtNm, prdtNm,
priceInfo, priceInfo,
rankOrd, rankOrd,
total,
} = targetItem; } = targetItem;
return ( return (
@@ -77,6 +76,8 @@ export default function ItemContents({ onClick }) {
onClick={_handleItemClick(patnrId, prdtId)} onClick={_handleItemClick(patnrId, prdtId)}
offerInfo={offerInfo} offerInfo={offerInfo}
spotlightId={"categoryItemContents" + index} spotlightId={"categoryItemContents" + index}
label={index * 1 + 1 + " of " + itemListDatas.total}
lastLabel=" go to detail, button"
/> />
); );
}, },

View File

@@ -18,7 +18,7 @@ export default function NoResultsCategoryItems() {
<div className={css.container}> <div className={css.container}>
<div className={css.info}> <div className={css.info}>
<div className={css.imageBox}> <div className={css.imageBox}>
<img src={NoResultsImage} alt="No Datas" /> <img src={NoResultsImage} alt="THERE ARE NO SHOWS AVAILABLE" />
</div> </div>
<p>{$L("THERE ARE NO ITEMS AVAILABLE")}</p> <p>{$L("THERE ARE NO ITEMS AVAILABLE")}</p>
</div> </div>
@@ -26,9 +26,16 @@ export default function NoResultsCategoryItems() {
<SectionTitle title={$L("BEST SELLER")} /> <SectionTitle title={$L("BEST SELLER")} />
<TGrid> <TGrid>
{bestSellerDatas && {bestSellerDatas &&
bestSellerDatas bestSellerDatas.slice(0, 5).map((bestSeller, index) => {
.slice(0, 5) const rankText =
.map((bestSeller) => ( bestSeller.rankOrd === 1
? bestSeller.rankOrd + "st"
: bestSeller.rankOrd === 2
? bestSeller.rankOrd + "nd"
: bestSeller.rankOrd === 3
? bestSeller.rankOrd + "rd"
: bestSeller.rankOrd + "th";
return (
<TItemCard <TItemCard
key={bestSeller.rankOrd} key={bestSeller.rankOrd}
imageSource={bestSeller.imgUrl} imageSource={bestSeller.imgUrl}
@@ -36,9 +43,13 @@ export default function NoResultsCategoryItems() {
productName={bestSeller.prdtNm} productName={bestSeller.prdtNm}
priceInfo={bestSeller.priceInfo} priceInfo={bestSeller.priceInfo}
rank={bestSeller.rankOrd} rank={bestSeller.rankOrd}
firstLabel={rankText}
label={index * 1 + 1 + " of 5"}
lastLabel=" go to detail, button"
isBestSeller isBestSeller
/> />
))} );
})}
</TGrid> </TGrid>
</div> </div>
</div> </div>

View File

@@ -10,7 +10,7 @@ export default function NoResultsCategoryShows() {
<div className={css.container}> <div className={css.container}>
<div className={css.info}> <div className={css.info}>
<div className={css.imageBox}> <div className={css.imageBox}>
<img src={NoResultsImage} alt="No Datas" /> <img src={NoResultsImage} alt="THERE ARE NO SHOWS AVAILABLE" />
</div> </div>
<p>{$L("THERE ARE NO SHOWS AVAILABLE")}</p> <p>{$L("THERE ARE NO SHOWS AVAILABLE")}</p>
</div> </div>

View File

@@ -1,23 +1,17 @@
import React, { useCallback } from 'react'; import React, { useCallback } from "react";
import { import { useDispatch, useSelector } from "react-redux";
useDispatch,
useSelector,
} from 'react-redux';
import SpotlightContainerDecorator import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
from '@enact/spotlight/SpotlightContainerDecorator'; import Spottable from "@enact/spotlight/Spottable";
import Spottable from '@enact/spotlight/Spottable';
import defaultImageShow import defaultImageShow from "../../../../../assets/images/img-thumb-empty-product@3x.png";
from '../../../../../assets/images/img-thumb-empty-product@3x.png'; import { startVideoPlayer } from "../../../../actions/playActions";
import { startVideoPlayer } from '../../../../actions/playActions'; import CustomImage from "../../../../components/CustomImage/CustomImage";
import CustomImage from '../../../../components/CustomImage/CustomImage'; import NoResultsCategoryShows from "../NoResultsCategory/NoResultsCategoryShows";
import NoResultsCategoryShows import css from "./ShowContents.module.less";
from '../NoResultsCategory/NoResultsCategoryShows'; import ShowLists from "./ShowLists/ShowLists";
import css from './ShowContents.module.less'; import ShowProductContents from "./ShowProductContents/ShowProductContents";
import ShowLists from './ShowLists/ShowLists';
import ShowProductContents from './ShowProductContents/ShowProductContents';
const SpottableVideoContainer = Spottable("div"); const SpottableVideoContainer = Spottable("div");
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator(
@@ -58,7 +52,12 @@ export default function ShowContents({ onClick }) {
<> <>
{topShowInfo && ( {topShowInfo && (
<> <>
<h1 className={css.topsTitle}>{topShowInfo.showNm}</h1> <h1
className={css.topsTitle}
aria-label={topShowInfo.showNm + ", Heading2"}
>
{topShowInfo.showNm}
</h1>
<Container className={css.topShowContainer}> <Container className={css.topShowContainer}>
<SpottableVideoContainer <SpottableVideoContainer
className={css.videoContainer} className={css.videoContainer}
@@ -69,6 +68,7 @@ export default function ShowContents({ onClick }) {
topShowInfo.showUrl topShowInfo.showUrl
)} )}
spotlightId={"category-topshow"} spotlightId={"category-topshow"}
aria-label={"1st, " + topShowInfo.showNm}
> >
<CustomImage <CustomImage
alt={topShowInfo.showNm} alt={topShowInfo.showNm}

View File

@@ -1,24 +1,16 @@
import React, { import React, { useCallback, useEffect } from "react";
useCallback,
useEffect,
} from 'react';
import { import { useDispatch, useSelector } from "react-redux";
useDispatch,
useSelector,
} from 'react-redux';
import SpotlightContainerDecorator import SpotlightContainerDecorator from "@enact/spotlight/SpotlightContainerDecorator";
from '@enact/spotlight/SpotlightContainerDecorator';
import { startVideoPlayer } from '../../../../../actions/playActions'; import { startVideoPlayer } from "../../../../../actions/playActions";
import TItemCard from '../../../../../components/TItemCard/TItemCard'; import TItemCard from "../../../../../components/TItemCard/TItemCard";
import TVirtualGridList import TVirtualGridList from "../../../../../components/TVirtualGridList/TVirtualGridList";
from '../../../../../components/TVirtualGridList/TVirtualGridList'; import useScrollTo from "../../../../../hooks/useScrollTo";
import useScrollTo from '../../../../../hooks/useScrollTo'; import { panel_names } from "../../../../../utils/Config";
import { panel_names } from '../../../../../utils/Config'; import { SpotlightIds } from "../../../../../utils/SpotlightIds";
import { SpotlightIds } from '../../../../../utils/SpotlightIds'; import css from "./ShowProductContents.module.less";
import css from './ShowProductContents.module.less';
const Container = SpotlightContainerDecorator( const Container = SpotlightContainerDecorator(
{ enterTo: "last-focused", leaveFor: { left: "", right: "" } }, { enterTo: "last-focused", leaveFor: { left: "", right: "" } },
@@ -77,6 +69,8 @@ export default function ShowProductContents({ onClick }) {
onClick={handleItemClick(index)} onClick={handleItemClick(index)}
offerInfo={offerInfo} offerInfo={offerInfo}
productId={prdtId} productId={prdtId}
label={index * 1 + 1 + " of " + productInfos.length}
lastLabel=" go to detail, button"
/> />
); );
}, },

View File

@@ -115,8 +115,9 @@ export default function CategoryPanel({ panelInfo, isOnTop }) {
: LOG_MENU.CATEGORY_ITEM; : LOG_MENU.CATEGORY_ITEM;
} }
} }
if (nowMenu) {
sendLogGNB(nowMenu); sendLogGNB(nowMenu);
}
}, [categoryItemInfos, categoryShowInfos, sendLogGNB, tab]); }, [categoryItemInfos, categoryShowInfos, sendLogGNB, tab]);
useEffect(() => { useEffect(() => {
@@ -349,7 +350,7 @@ export default function CategoryPanel({ panelInfo, isOnTop }) {
return ( return (
<TPanel> <TPanel>
<THeader title="CATEGORY" /> <THeader title="CATEGORY" ariaLabel="CATEGORY, HEADING 1" />
{categoryDatas && ( {categoryDatas && (
<TBody <TBody
className={css.tBody} className={css.tBody}
@@ -363,6 +364,7 @@ export default function CategoryPanel({ panelInfo, isOnTop }) {
title={lgCatNm} title={lgCatNm}
className={css.title} className={css.title}
itemCount={itemCountNumbers} itemCount={itemCountNumbers}
ariaLabel={lgCatNm}
/> />
)} )}
{buttonTabList && buttonTabList.length > 0 && ( {buttonTabList && buttonTabList.length > 0 && (
@@ -397,6 +399,7 @@ export default function CategoryPanel({ panelInfo, isOnTop }) {
type={TYPES.topButton} type={TYPES.topButton}
size={null} size={null}
onClick={handleTopButtonClick} onClick={handleTopButtonClick}
ariaLabel="Move to Top, Button"
/> />
)} )}
</div> </div>