Skip to content

Commit

Permalink
#5422 for Image
Browse files Browse the repository at this point in the history
  • Loading branch information
gucal committed Nov 28, 2023
1 parent 081170e commit 90000e4
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 67 deletions.
105 changes: 51 additions & 54 deletions components/doc/image/accessibilitydoc.js
Original file line number Diff line number Diff line change
@@ -1,65 +1,62 @@
import { DevelopmentSection } from '@/components/doc/common/developmentsection';
import { DocSectionText } from '@/components/doc/common/docsectiontext';

import Link from 'next/link';

export function AccessibilityDoc() {
return (
<DevelopmentSection>
<DocSectionText id="accessibility" label="Accessibility">
<h3>Screen Reader</h3>
<p>
The preview button is a native <i>button</i> element with an <i>aria-label</i> that refers to the <i>aria.zoomImage</i> property of the <Link href="/locale">locale</Link> API by default, with <i>previewButtonProps</i>
you may use your own aria roles and attributes as any valid attribute is passed to the button element implicitly.
</p>
<DocSectionText id="accessibility" label="Accessibility">
<h3>Screen Reader</h3>
<p>
The preview button is a native <i>button</i> element with an <i>aria-label</i> that refers to the <i>aria.zoomImage</i> property of the <Link href="/locale">locale</Link> API by default, with <i>previewButtonProps</i>
you may use your own aria roles and attributes as any valid attribute is passed to the button element implicitly.
</p>

<p>
When preview is active, <i>dialog</i> role with <i>aria-modal</i> is applied to the overlay image container.
</p>
<p>
When preview is active, <i>dialog</i> role with <i>aria-modal</i> is applied to the overlay image container.
</p>

<p>
Button controls use <i>aria.rotateRight</i>, <i>aria.rotateLeft</i>, <i>aria.zoomIn</i>, <i>aria.zoomOut</i> and <i>aria.close</i> from the <Link href="/locale">locale</Link> API as <i>aria-label</i>.
</p>
<p>
Button controls use <i>aria.rotateRight</i>, <i>aria.rotateLeft</i>, <i>aria.zoomIn</i>, <i>aria.zoomOut</i> and <i>aria.close</i> from the <Link href="/locale">locale</Link> API as <i>aria-label</i>.
</p>

<h3>ButtonBar Keyboard Support</h3>
<p>When preview is activated, close button receives the initial focus.</p>
<div className="doc-tablewrapper">
<table className="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus through button bar.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Activates the button.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Activates the button.</td>
</tr>
<tr>
<td>
<i>esc</i>
</td>
<td>Closes the image preview.</td>
</tr>
</tbody>
</table>
</div>
</DocSectionText>
</DevelopmentSection>
<h3>ButtonBar Keyboard Support</h3>
<p>When preview is activated, close button receives the initial focus.</p>
<div className="doc-tablewrapper">
<table className="doc-table">
<thead>
<tr>
<th>Key</th>
<th>Function</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<i>tab</i>
</td>
<td>Moves focus through button bar.</td>
</tr>
<tr>
<td>
<i>enter</i>
</td>
<td>Activates the button.</td>
</tr>
<tr>
<td>
<i>space</i>
</td>
<td>Activates the button.</td>
</tr>
<tr>
<td>
<i>esc</i>
</td>
<td>Closes the image preview.</td>
</tr>
</tbody>
</table>
</div>
</DocSectionText>
);
}
76 changes: 63 additions & 13 deletions components/lib/image/Image.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ export const Image = React.memo(
const maskRef = React.useRef(null);
const previewRef = React.useRef(null);
const previewClick = React.useRef(false);
const previewButton = React.useRef(null);

useOnEscapeKey(maskRef, props.closeOnEscape, () => {
hide();
});

const { ptm, cx, sx, isUnstyled } = ImageBase.setMetaData({
props,
state: {
Expand Down Expand Up @@ -70,6 +72,38 @@ export const Image = React.memo(
previewClick.current = true;
};

const onMaskClick = (event) => {
const isActionbarTarget = [event.target.classList].includes('p-image-action') || event.target.closest('.p-image-action');

if (isActionbarTarget) {
return;
}

if (!previewClick.current) {
setPreviewVisibleState(false);
rotate = 0;
scale = 0;
}

previewClick.current = false;
};

const onMaskKeydown = (event) => {
switch (event.code) {
case 'Escape':
hide();
setTimeout(() => {
DomHandler.focus(previewButton.current);
}, 200);
event.preventDefault();

break;

default:
break;
}
};

const onDownload = () => {
const { alt: name, src } = props;

Expand Down Expand Up @@ -126,14 +160,16 @@ export const Image = React.memo(
const createPreview = () => {
const buttonProps = mergeProps(
{
ref: previewButton,
className: cx('button'),
onClick: show
onClick: show,
type: 'button'
},
ptm('button')
);

if (props.preview) {
return <div {...buttonProps}>{content}</div>;
return <button {...buttonProps}>{content}</button>;
}

return null;
Expand All @@ -159,8 +195,11 @@ export const Image = React.memo(
const maskProps = mergeProps(
{
ref: maskRef,
role: 'dialog',
className: cx('mask'),
onPointerUp: hide
'aria-modal': maskVisibleState,
onClick: onMaskClick,
onKeyDown: onMaskKeydown
},
ptm('mask')
);
Expand All @@ -184,17 +223,21 @@ export const Image = React.memo(
const rotateRightButtonProps = mergeProps(
{
className: cx('rotateRightButton'),
onPointerUp: rotateRight,
type: 'button'
onClick: rotateRight,
type: 'button',
'aria-label': localeOption('aria') ? localeOption('aria').rotateRight : undefined,
'data-pc-group-section': 'action'
},
ptm('rotateRightButton')
);

const rotateLeftButtonProps = mergeProps(
{
className: cx('rotateLeftButton'),
onPointerUp: rotateLeft,
type: 'button'
onClick: rotateLeft,
type: 'button',
'aria-label': localeOption('aria') ? localeOption('aria').rotateLeft : undefined,
'data-pc-group-section': 'action'
},
ptm('rotateLeftButton')
);
Expand All @@ -203,9 +246,11 @@ export const Image = React.memo(
{
className: classNames(cx('zoomOutButton'), { 'p-disabled': zoomOutDisabled }),
style: { pointerEvents: 'auto' },
onPointerUp: zoomOut,
onClick: zoomOut,
type: 'button',
disabled: zoomOutDisabled
disabled: zoomOutDisabled,
'aria-label': localeOption('aria') ? localeOption('aria').zoomOut : undefined,
'data-pc-group-section': 'action'
},
ptm('zoomOutButton')
);
Expand All @@ -214,9 +259,11 @@ export const Image = React.memo(
{
className: classNames(cx('zoomInButton'), { 'p-disabled': zoomInDisabled }),
style: { pointerEvents: 'auto' },
onPointerUp: zoomIn,
onClick: zoomIn,
type: 'button',
disabled: zoomInDisabled
disabled: zoomInDisabled,
'aria-label': localeOption('aria') ? localeOption('aria').zoomIn : undefined,
'data-pc-group-section': 'action'
},
ptm('zoomInButton')
);
Expand All @@ -225,7 +272,10 @@ export const Image = React.memo(
{
className: cx('closeButton'),
type: 'button',
'aria-label': localeOption('close')
onClick: hide,
'aria-label': localeOption('aria') ? localeOption('aria').close : undefined,
autoFocus: true,
'data-pc-group-section': 'action'
},
ptm('closeButton')
);
Expand All @@ -235,7 +285,7 @@ export const Image = React.memo(
src: props.zoomSrc || props.src,
className: cx('preview'),
style: sx('preview', { rotateState, scaleState }),
onPointerUp: onPreviewImageClick,
onClick: onPreviewImageClick,
crossOrigin: crossOrigin,
referrerPolicy: referrerPolicy,
useMap: useMap,
Expand Down

0 comments on commit 90000e4

Please sign in to comment.