Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions .changeset/green-rules-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Improves color contrast in image gallery icon buttons to meet WCAG compliance.
166 changes: 90 additions & 76 deletions apps/meteor/client/components/ImageGallery/ImageGallery.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IUpload } from '@rocket.chat/core-typings';
import { css } from '@rocket.chat/css-in-js';
import { Box, ButtonGroup, IconButton, Palette, Throbber } from '@rocket.chat/fuselage';
import { Box, ButtonGroup, IconButton, Palette, PaletteStyleTag, Throbber, padding } from '@rocket.chat/fuselage';
import { useRef, useState } from 'react';
import { FocusScope } from 'react-aria';
import { createPortal } from 'react-dom';
Expand Down Expand Up @@ -32,10 +32,8 @@ const swiperStyle = css`
background-color: var(--rcx-color-surface-overlay, rgba(0, 0, 0, 0.6));
}

.rcx-swiper-close-button,
.rcx-swiper-prev-button,
.rcx-swiper-next-button {
color: var(--rcx-color-font-pure-white, #ffffff) !important;
.swiper-slide {
padding: ${padding('x144')} ${padding('x60')} ${padding('x96')};
}

.rcx-swiper-prev-button,
Expand Down Expand Up @@ -96,11 +94,7 @@ const swiperStyle = css`
width: 100%;
display: flex;
justify-content: flex-end;
transition: background-color 0.2s;
&:hover {
background-color: ${Palette.surface['surface-overlay']};
transition: background-color 0.2s;
}
background-color: ${Palette.surface['surface-sidebar']};
}
`;

Expand All @@ -126,77 +120,97 @@ export const ImageGallery = ({ images, onClose, loadMore }: { images: IUpload[];
const preventPropagation = usePreventPropagation();

return createPortal(
<FocusScope contain autoFocus>
<Box role='dialog' aria-modal='true' aria-label={t('Image_gallery')} className={swiperStyle}>
<div role='presentation' className='swiper-container' onClick={onClose}>
<ButtonGroup role='toolbar' className='rcx-swiper-controls' onClick={preventPropagation}>
{zoomScale !== 1 && (
<IconButton name='resize' small icon='arrow-collapse' title={t('Resize')} rcx-swiper-zoom-out onClick={handleResize} />
)}
<>
<PaletteStyleTag theme='dark' selector='.swiper-container.image-gallery' tagId='image-gallery-palette' />
<FocusScope contain autoFocus>
<Box role='dialog' aria-modal='true' aria-label={t('Image_gallery')} className={swiperStyle}>
<div role='presentation' className='swiper-container image-gallery' onClick={onClose}>
<ButtonGroup role='toolbar' className='rcx-swiper-controls' onClick={preventPropagation}>
{zoomScale !== 1 && (
<IconButton
name='resize'
small
icon='arrow-collapse'
title={t('Resize')}
rcx-swiper-zoom-out
secondary
onClick={handleResize}
/>
)}
<IconButton
name='zoom-out'
small
icon='h-bar'
title={t('Zoom_out')}
rcx-swiper-zoom-out
onClick={handleZoomOut}
secondary
disabled={zoomScale === 1}
/>
<IconButton name='zoom-in' small icon='plus' title={t('Zoom_in')} rcx-swiper-zoom-in secondary onClick={handleZoomIn} />
<IconButton
name='close'
small
icon='cross'
aria-label={t('Close_gallery')}
className='rcx-swiper-close-button'
secondary
onClick={onClose}
/>
</ButtonGroup>
<IconButton
name='zoom-out'
small
icon='h-bar'
title={t('Zoom_out')}
rcx-swiper-zoom-out
onClick={handleZoomOut}
disabled={zoomScale === 1}
icon='chevron-right'
aria-label={t('Next_image')}
className='rcx-swiper-prev-button'
secondary
onClick={preventPropagation}
/>
<IconButton name='zoom-in' small icon='plus' title={t('Zoom_in')} rcx-swiper-zoom-in onClick={handleZoomIn} />
<IconButton
name='close'
small
icon='cross'
aria-label={t('Close_gallery')}
className='rcx-swiper-close-button'
onClick={onClose}
icon='chevron-left'
aria-label={t('Previous_image')}
className='rcx-swiper-next-button'
secondary
onClick={preventPropagation}
/>
</ButtonGroup>
<IconButton icon='chevron-right' aria-label={t('Next_image')} className='rcx-swiper-prev-button' onClick={preventPropagation} />
<IconButton
icon='chevron-left'
aria-label={t('Previous_image')}
className='rcx-swiper-next-button'
onClick={preventPropagation}
/>
<Swiper
ref={swiperRef}
navigation={{
nextEl: '.rcx-swiper-next-button',
prevEl: '.rcx-swiper-prev-button',
}}
keyboard
zoom={{ toggle: false }}
lazyPreloaderClass='rcx-lazy-preloader'
runCallbacksOnInit
onKeyPress={(_: SwiperClass, keyCode: string) => String(keyCode) === '27' && onClose()}
modules={[Navigation, Zoom, Keyboard, A11y]}
onInit={(swiper: SwiperClass) => setSwiperInst(swiper)}
onSlidesGridLengthChange={(swiper: SwiperClass) => {
swiper.slideTo(images.length - gridSize, 0);
setGridSize(images.length);
}}
onReachBeginning={loadMore}
initialSlide={images.length - 1}
>
{[...images].reverse().map(({ _id, path, url }) => (
<SwiperSlide key={_id}>
<div className='swiper-zoom-container'>
{/* eslint-disable-next-line
jsx-a11y/no-noninteractive-element-interactions,
jsx-a11y/click-events-have-key-events
*/}
<img src={path || url} loading='lazy' alt='' data-qa-zoom-scale={zoomScale} onClick={preventPropagation} />
<div className='rcx-lazy-preloader'>
<Throbber inheritColor />
<Swiper
ref={swiperRef}
navigation={{
nextEl: '.rcx-swiper-next-button',
prevEl: '.rcx-swiper-prev-button',
}}
keyboard
zoom={{ toggle: false }}
lazyPreloaderClass='rcx-lazy-preloader'
runCallbacksOnInit
onKeyPress={(_: SwiperClass, keyCode: string) => String(keyCode) === '27' && onClose()}
modules={[Navigation, Zoom, Keyboard, A11y]}
onInit={(swiper: SwiperClass) => setSwiperInst(swiper)}
onSlidesGridLengthChange={(swiper: SwiperClass) => {
swiper.slideTo(images.length - gridSize, 0);
setGridSize(images.length);
}}
onReachBeginning={loadMore}
initialSlide={images.length - 1}
>
{[...images].reverse().map(({ _id, path, url }) => (
<SwiperSlide key={_id}>
<div className='swiper-zoom-container'>
{/* eslint-disable-next-line
jsx-a11y/no-noninteractive-element-interactions,
jsx-a11y/click-events-have-key-events
*/}
<img src={path || url} loading='lazy' alt='' data-qa-zoom-scale={zoomScale} onClick={preventPropagation} />
<div className='rcx-lazy-preloader'>
<Throbber inheritColor />
</div>
</div>
</div>
</SwiperSlide>
))}
</Swiper>
</div>
</Box>
</FocusScope>,
</SwiperSlide>
))}
</Swiper>
</div>
</Box>
</FocusScope>
</>,
document.body,
);
};
Loading