Merge pull request #15018 from itk-dev/feature/interface-tab-settings-modal-accessibility

Feat: interface tab settings modal accessibility
This commit is contained in:
Tim Jaeryang Baek 2025-06-16 14:25:01 +04:00 committed by GitHub
commit b8103807cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -385,15 +385,16 @@
<div class=" space-y-3 overflow-y-scroll max-h-[28rem] lg:max-h-full"> <div class=" space-y-3 overflow-y-scroll max-h-[28rem] lg:max-h-full">
<div> <div>
<div class=" mb-1.5 text-sm font-medium">{$i18n.t('UI')}</div> <h1 class=" mb-1.5 text-sm font-medium">{$i18n.t('UI')}</h1>
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="high-contrast-mode-label" class=" self-center text-xs">
{$i18n.t('High Contrast Mode')} ({$i18n.t('Beta')}) {$i18n.t('High Contrast Mode')} ({$i18n.t('Beta')})
</div> </div>
<button <button
aria-labelledby="high-contrast-mode-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleHighContrastMode(); toggleHighContrastMode();
@ -411,9 +412,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Landing Page Mode')}</div> <div id="landing-page-mode-label" class=" self-center text-xs">{$i18n.t('Landing Page Mode')}</div>
<button <button
aria-labelledby="landing-page-mode-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleLandingPageMode(); toggleLandingPageMode();
@ -431,9 +433,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Chat Bubble UI')}</div> <div id="chat-bubble-ui-label" class=" self-center text-xs">{$i18n.t('Chat Bubble UI')}</div>
<button <button
aria-labelledby="chat-bubble-ui-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleChatBubble(); toggleChatBubble();
@ -452,11 +455,12 @@
{#if !$settings.chatBubble} {#if !$settings.chatBubble}
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="chat-bubble-username-label" class=" self-center text-xs">
{$i18n.t('Display the username instead of You in the Chat')} {$i18n.t('Display the username instead of You in the Chat')}
</div> </div>
<button <button
aria-labelledby="chat-bubble-username-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleShowUsername(); toggleShowUsername();
@ -475,13 +479,14 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Widescreen Mode')}</div> <div id="widescreen-mode-label" class=" self-center text-xs">{$i18n.t('Widescreen Mode')}</div>
<button <button
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleWidescreenMode(); toggleWidescreenMode();
}} }}
aria-labelledby="widescreen-mode-label"
type="button" type="button"
> >
{#if widescreenMode === true} {#if widescreenMode === true}
@ -495,9 +500,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Chat direction')}</div> <div id="chat-direction-label" class=" self-center text-xs">{$i18n.t('Chat direction')}</div>
<button <button
aria-labelledby="chat-direction-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={toggleChangeChatDirection} on:click={toggleChangeChatDirection}
type="button" type="button"
@ -514,12 +520,13 @@
</div> </div>
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class="py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id=""notification-sound-label"" class=" self-center text-xs">
{$i18n.t('Notification Sound')} {$i18n.t('Notification Sound')}
</div> </div>
<button <button
aria-labelledby="notification-sound-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleNotificationSound(); toggleNotificationSound();
@ -538,11 +545,12 @@
{#if notificationSound} {#if notificationSound}
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="play-notification-sound-label" class=" self-center text-xs">
{$i18n.t('Always Play Notification Sound')} {$i18n.t('Always Play Notification Sound')}
</div> </div>
<button <button
aria-labelledby="play-notification-sound-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleNotificationSoundAlways(); toggleNotificationSoundAlways();
@ -562,11 +570,12 @@
{#if $user?.role === 'admin'} {#if $user?.role === 'admin'}
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="toast-notifications-label" class=" self-center text-xs">
{$i18n.t('Toast notifications for new updates')} {$i18n.t('Toast notifications for new updates')}
</div> </div>
<button <button
aria-labelledby="toast-notifications-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleShowUpdateToast(); toggleShowUpdateToast();
@ -584,11 +593,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="whats-new-label" class=" self-center text-xs">
{$i18n.t(`Show "What's New" modal on login`)} {$i18n.t(`Show "What's New" modal on login`)}
</div> </div>
<button <button
aria-labelledby="whats-new-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleShowChangelog(); toggleShowChangelog();
@ -609,9 +619,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Title Auto-Generation')}</div> <div id="auto-generation-label" class=" self-center text-xs">{$i18n.t('Title Auto-Generation')}</div>
<button <button
aria-labelledby="auto-generation-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleTitleAutoGenerate(); toggleTitleAutoGenerate();
@ -632,6 +643,7 @@
<div class=" self-center text-xs">{$i18n.t('Follow-Up Auto-Generation')}</div> <div class=" self-center text-xs">{$i18n.t('Follow-Up Auto-Generation')}</div>
<button <button
aria-labelledby="auto-generation-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleAutoFollowUps(); toggleAutoFollowUps();
@ -649,9 +661,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Chat Tags Auto-Generation')}</div> <div id="chat-tags-label" class=" self-center text-xs">{$i18n.t('Chat Tags Auto-Generation')}</div>
<button <button
aria-labelledby="chat-tags-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleAutoTags(); toggleAutoTags();
@ -669,11 +682,13 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="detect-artifacts-label" class=" self-center text-xs">
{$i18n.t('Detect Artifacts Automatically')} {$i18n.t('Detect Artifacts Automatically')}
</div> </div>
<button <button
aria-labelledby="detect-artifacts-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleDetectArtifacts(); toggleDetectArtifacts();
@ -691,11 +706,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="auto-copy-label" class=" self-center text-xs">
{$i18n.t('Auto-Copy Response to Clipboard')} {$i18n.t('Auto-Copy Response to Clipboard')}
</div> </div>
<button <button
aria-labelledby="auto-copy-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleResponseAutoCopy(); toggleResponseAutoCopy();
@ -713,11 +729,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="rich-input-label" class=" self-center text-xs">
{$i18n.t('Rich Text Input for Chat')} {$i18n.t('Rich Text Input for Chat')}
</div> </div>
<button <button
aria-labelledby="rich-input-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleRichTextInput(); toggleRichTextInput();
@ -736,11 +753,12 @@
{#if $config?.features?.enable_autocomplete_generation && richTextInput} {#if $config?.features?.enable_autocomplete_generation && richTextInput}
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="prompt-autocompletion-label" class=" self-center text-xs">
{$i18n.t('Prompt Autocompletion')} {$i18n.t('Prompt Autocompletion')}
</div> </div>
<button <button
aria-labelledby="prompt-autocompletion-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
togglePromptAutocomplete(); togglePromptAutocomplete();
@ -759,11 +777,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="paste-large-label" class=" self-center text-xs">
{$i18n.t('Paste Large Text as File')} {$i18n.t('Paste Large Text as File')}
</div> </div>
<button <button
aria-labelledby="paste-large-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleLargeTextAsFile(); toggleLargeTextAsFile();
@ -781,11 +800,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="copy-formatted-label" class=" self-center text-xs">
{$i18n.t('Copy Formatted Text')} {$i18n.t('Copy Formatted Text')}
</div> </div>
<button <button
aria-labelledby="copy-formatted-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleCopyFormatted(); toggleCopyFormatted();
@ -803,9 +823,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Always Collapse Code Blocks')}</div> <div id="always-collapse-label" class=" self-center text-xs">{$i18n.t('Always Collapse Code Blocks')}</div>
<button <button
aria-labelledby="always-collapse-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleCollapseCodeBlocks(); toggleCollapseCodeBlocks();
@ -823,9 +844,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Always Expand Details')}</div> <div id="always-expand-label" class=" self-center text-xs">{$i18n.t('Always Expand Details')}</div>
<button <button
aria-labelledby="always-expand-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleExpandDetails(); toggleExpandDetails();
@ -843,11 +865,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="chat-background-label" class=" self-center text-xs">
{$i18n.t('Chat Background Image')} {$i18n.t('Chat Background Image')}
</div> </div>
<button <button
aria-labelledby="chat-background-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
if (backgroundImageUrl !== null) { if (backgroundImageUrl !== null) {
@ -869,10 +892,11 @@
</div> </div>
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div id="allow-user-location-label" class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Allow User Location')}</div> <div class=" self-center text-xs">{$i18n.t('Allow User Location')}</div>
<button <button
aria-labelledby="allow-user-location-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleUserLocation(); toggleUserLocation();
@ -890,11 +914,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="haptic-feedback-label" class=" self-center text-xs">
{$i18n.t('Haptic Feedback')} ({$i18n.t('Android')}) {$i18n.t('Haptic Feedback')} ({$i18n.t('Android')})
</div> </div>
<button <button
aria-labelledby="haptic-feedback-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleHapticFeedback(); toggleHapticFeedback();
@ -912,11 +937,12 @@
<!-- <div> <!-- <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="fluidly-stream-label" class=" self-center text-xs">
{$i18n.t('Fluidly stream large external response chunks')} {$i18n.t('Fluidly stream large external response chunks')}
</div> </div>
<button <button
aria-labelledby="fluidly-stream-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleSplitLargeChunks(); toggleSplitLargeChunks();
@ -934,11 +960,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="enter-key-behavior-label" class=" self-center text-xs">
{$i18n.t('Enter Key Behavior')} {$i18n.t('Enter Key Behavior')}
</div> </div>
<button <button
aria-labelledby="enter-key-behavior-label"
class="p-1 px-3 text-xs flex rounded transition" class="p-1 px-3 text-xs flex rounded transition"
on:click={() => { on:click={() => {
togglectrlEnterToSend(); togglectrlEnterToSend();
@ -956,11 +983,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="scroll-on-branch-change-label" class=" self-center text-xs">
{$i18n.t('Scroll On Branch Change')} {$i18n.t('Scroll On Branch Change')}
</div> </div>
<button <button
aria-labelledby="scroll-on-branch-change-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
togglesScrollOnBranchChange(); togglesScrollOnBranchChange();
@ -978,9 +1006,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Web Search in Chat')}</div> <div id="web-search-in-chat-label" class=" self-center text-xs">{$i18n.t('Web Search in Chat')}</div>
<button <button
aria-labelledby="web-search-in-chat-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleWebSearch(); toggleWebSearch();
@ -998,9 +1027,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('iframe Sandbox Allow Same Origin')}</div> <div id="iframe-sandbox-allow-same-origin-label" class=" self-center text-xs">{$i18n.t('iframe Sandbox Allow Same Origin')}</div>
<button <button
aria-labelledby="iframe-sandbox-allow-same-origin-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleIframeSandboxAllowSameOrigin(); toggleIframeSandboxAllowSameOrigin();
@ -1018,9 +1048,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('iframe Sandbox Allow Forms')}</div> <div id="iframe-sandbox-allow-forms-label" class=" self-center text-xs">{$i18n.t('iframe Sandbox Allow Forms')}</div>
<button <button
aria-labelledby="iframe-sandbox-allow-forms-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleIframeSandboxAllowForms(); toggleIframeSandboxAllowForms();
@ -1038,11 +1069,12 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs"> <div id="stylized-pdf-export-label" class=" self-center text-xs">
{$i18n.t('Stylized PDF Export')} {$i18n.t('Stylized PDF Export')}
</div> </div>
<button <button
aria-labelledby="stylized-pdf-export-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleStylizedPdfExport(); toggleStylizedPdfExport();
@ -1065,6 +1097,7 @@
<div class=" self-center text-xs">{$i18n.t('Allow Voice Interruption in Call')}</div> <div class=" self-center text-xs">{$i18n.t('Allow Voice Interruption in Call')}</div>
<button <button
aria-labelledby="allow-voice-interruption-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleVoiceInterruption(); toggleVoiceInterruption();
@ -1082,9 +1115,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Display Emoji in Call')}</div> <div id="display-emoji-label" class=" self-center text-xs">{$i18n.t('Display Emoji in Call')}</div>
<button <button
aria-labelledby="display-emoji-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleEmojiInCall(); toggleEmojiInCall();
@ -1104,9 +1138,10 @@
<div> <div>
<div class=" py-0.5 flex w-full justify-between"> <div class=" py-0.5 flex w-full justify-between">
<div class=" self-center text-xs">{$i18n.t('Image Compression')}</div> <div id="image-compression-label" class=" self-center text-xs">{$i18n.t('Image Compression')}</div>
<button <button
aria-labelledby="image-compression-label"
class="p-1 px-3 text-xs flex rounded-sm transition" class="p-1 px-3 text-xs flex rounded-sm transition"
on:click={() => { on:click={() => {
toggleImageCompression(); toggleImageCompression();
@ -1125,9 +1160,10 @@
{#if imageCompression} {#if imageCompression}
<div> <div>
<div class=" py-0.5 flex w-full justify-between text-xs"> <div class=" py-0.5 flex w-full justify-between text-xs">
<div class=" self-center text-xs">{$i18n.t('Image Max Compression Size')}</div> <div id="image-compression-size-label" class=" self-center text-xs">{$i18n.t('Image Max Compression Size')}</div>
<div> <div>
<label class="sr-only" for="image-comp-width">{$i18n.t('Image Max Compression Size width')}</label>
<input <input
bind:value={imageCompressionSize.width} bind:value={imageCompressionSize.width}
type="number" type="number"
@ -1135,6 +1171,7 @@
min="0" min="0"
placeholder="Width" placeholder="Width"
/>x />x
<label class="sr-only" for="image-comp-height">{$i18n.t('Image Max Compression Size height')}</label>
<input <input
bind:value={imageCompressionSize.height} bind:value={imageCompressionSize.height}
type="number" type="number"