mirror of
https://github.com/mastodon/mastodon.git
synced 2025-01-23 18:41:42 +01:00
Add information about alt text to alt text modal in web UI (#33702)
This commit is contained in:
parent
db146046c4
commit
0885c31633
@ -0,0 +1,81 @@
|
|||||||
|
import { useState, useRef, useCallback, useId } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import Overlay from 'react-overlays/Overlay';
|
||||||
|
|
||||||
|
import QuestionMarkIcon from '@/material-icons/400-24px/question_mark.svg?react';
|
||||||
|
import { Icon } from 'mastodon/components/icon';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
help: { id: 'info_button.label', defaultMessage: 'Help' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const InfoButton: React.FC = () => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const triggerRef = useRef<HTMLButtonElement>(null);
|
||||||
|
const accessibilityId = useId();
|
||||||
|
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
setOpen(!open);
|
||||||
|
}, [open, setOpen]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className={classNames('help-button', { active: open })}
|
||||||
|
ref={triggerRef}
|
||||||
|
onClick={handleClick}
|
||||||
|
aria-expanded={open}
|
||||||
|
aria-controls={accessibilityId}
|
||||||
|
aria-label={intl.formatMessage(messages.help)}
|
||||||
|
>
|
||||||
|
<Icon id='' icon={QuestionMarkIcon} />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Overlay
|
||||||
|
show={open}
|
||||||
|
rootClose
|
||||||
|
placement='top'
|
||||||
|
onHide={handleClick}
|
||||||
|
offset={[5, 5]}
|
||||||
|
target={triggerRef}
|
||||||
|
>
|
||||||
|
{({ props }) => (
|
||||||
|
<div
|
||||||
|
{...props}
|
||||||
|
className='dialog-modal__popout prose dropdown-animation'
|
||||||
|
id={accessibilityId}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='info_button.what_is_alt_text'
|
||||||
|
defaultMessage='<h1>What is alt text?</h1>
|
||||||
|
|
||||||
|
<p>Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.</p>
|
||||||
|
|
||||||
|
<p>You can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Capture important elements</li>
|
||||||
|
<li>Summarize text in images</li>
|
||||||
|
<li>Use regular sentence structure</li>
|
||||||
|
<li>Avoid redundant information</li>
|
||||||
|
<li>Focus on trends and key findings in complex visuals (like diagrams or maps)</li>
|
||||||
|
</ul>'
|
||||||
|
values={{
|
||||||
|
h1: (node) => <h1>{node}</h1>,
|
||||||
|
p: (node) => <p>{node}</p>,
|
||||||
|
ul: (node) => <ul>{node}</ul>,
|
||||||
|
li: (node) => <li>{node}</li>,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Overlay>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -36,6 +36,8 @@ import type { MediaAttachment } from 'mastodon/models/media_attachment';
|
|||||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||||
import { assetHost } from 'mastodon/utils/config';
|
import { assetHost } from 'mastodon/utils/config';
|
||||||
|
|
||||||
|
import { InfoButton } from './components/info_button';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
placeholderVisual: {
|
placeholderVisual: {
|
||||||
id: 'alt_text_modal.describe_for_people_with_visual_impairments',
|
id: 'alt_text_modal.describe_for_people_with_visual_impairments',
|
||||||
@ -504,6 +506,13 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='input__toolbar'>
|
<div className='input__toolbar'>
|
||||||
|
<CharacterCounter
|
||||||
|
max={MAX_LENGTH}
|
||||||
|
text={isDetecting ? '' : description}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className='spacer' />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
className='link-button'
|
className='link-button'
|
||||||
onClick={handleDetectClick}
|
onClick={handleDetectClick}
|
||||||
@ -515,10 +524,7 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
|
|||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<CharacterCounter
|
<InfoButton />
|
||||||
max={MAX_LENGTH}
|
|
||||||
text={isDetecting ? '' : description}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -414,6 +414,8 @@
|
|||||||
"ignore_notifications_modal.not_followers_title": "Ignore notifications from people not following you?",
|
"ignore_notifications_modal.not_followers_title": "Ignore notifications from people not following you?",
|
||||||
"ignore_notifications_modal.not_following_title": "Ignore notifications from people you don't follow?",
|
"ignore_notifications_modal.not_following_title": "Ignore notifications from people you don't follow?",
|
||||||
"ignore_notifications_modal.private_mentions_title": "Ignore notifications from unsolicited Private Mentions?",
|
"ignore_notifications_modal.private_mentions_title": "Ignore notifications from unsolicited Private Mentions?",
|
||||||
|
"info_button.label": "Help",
|
||||||
|
"info_button.what_is_alt_text": "<h1>What is alt text?</h1> <p>Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.</p> <p>You can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.</p> <ul> <li>Capture important elements</li> <li>Summarize text in images</li> <li>Use regular sentence structure</li> <li>Avoid redundant information</li> <li>Focus on trends and key findings in complex visuals (like diagrams or maps)</li> </ul>",
|
||||||
"interaction_modal.action.favourite": "To continue, you need to favorite from your account.",
|
"interaction_modal.action.favourite": "To continue, you need to favorite from your account.",
|
||||||
"interaction_modal.action.follow": "To continue, you need to follow from your account.",
|
"interaction_modal.action.follow": "To continue, you need to follow from your account.",
|
||||||
"interaction_modal.action.reblog": "To continue, you need to reblog from your account.",
|
"interaction_modal.action.reblog": "To continue, you need to reblog from your account.",
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M424-320q0-81 14.5-116.5T500-514q41-36 62.5-62.5T584-637q0-41-27.5-68T480-732q-51 0-77.5 31T365-638l-103-44q21-64 77-111t141-47q105 0 161.5 58.5T698-641q0 50-21.5 85.5T609-475q-49 47-59.5 71.5T539-320H424Zm56 240q-33 0-56.5-23.5T400-160q0-33 23.5-56.5T480-240q33 0 56.5 23.5T560-160q0 33-23.5 56.5T480-80Z"/></svg>
|
After Width: | Height: | Size: 411 B |
1
app/javascript/material-icons/400-24px/question_mark.svg
Normal file
1
app/javascript/material-icons/400-24px/question_mark.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M424-320q0-81 14.5-116.5T500-514q41-36 62.5-62.5T584-637q0-41-27.5-68T480-732q-51 0-77.5 31T365-638l-103-44q21-64 77-111t141-47q105 0 161.5 58.5T698-641q0 50-21.5 85.5T609-475q-49 47-59.5 71.5T539-320H424Zm56 240q-33 0-56.5-23.5T400-160q0-33 23.5-56.5T480-240q33 0 56.5 23.5T560-160q0 33-23.5 56.5T480-80Z"/></svg>
|
After Width: | Height: | Size: 411 B |
@ -50,6 +50,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.help-button {
|
||||||
|
background: $ui-button-background-color;
|
||||||
|
border: 0;
|
||||||
|
color: $ui-button-color;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
&:active,
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
background-color: $ui-button-focus-background-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:focus-visible {
|
||||||
|
outline: $ui-button-icon-focus-outline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
background-color: $ui-button-background-color;
|
background-color: $ui-button-background-color;
|
||||||
border: 10px none;
|
border: 10px none;
|
||||||
@ -6091,6 +6119,20 @@ a.status-card {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__popout {
|
||||||
|
background: var(--dropdown-background-color);
|
||||||
|
backdrop-filter: var(--background-filter);
|
||||||
|
border: 1px solid var(--dropdown-border-color);
|
||||||
|
box-shadow: var(--dropdown-shadow);
|
||||||
|
max-width: 320px;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
z-index: 9999 !important;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
}
|
||||||
|
|
||||||
.copy-paste-text {
|
.copy-paste-text {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@ -83,9 +83,12 @@ code {
|
|||||||
&__toolbar {
|
&__toolbar {
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
|
.character-counter {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.hidden {
|
&.hidden {
|
||||||
@ -565,7 +568,7 @@ code {
|
|||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:not(.button, .link-button) {
|
button:not(.button, .link-button, .help-button) {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user