Merge pull request #15101 from itk-dev/feature/high-contrast-mode-tools-section

FEAT: high contrast mode tools section
This commit is contained in:
Tim Jaeryang Baek 2025-06-18 12:34:24 +04:00 committed by GitHub
commit 294d6ce060
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 55 additions and 19 deletions

View File

@ -3,6 +3,7 @@
import { getContext, onMount } from 'svelte'; import { getContext, onMount } from 'svelte';
const i18n = getContext('i18n'); const i18n = getContext('i18n');
import { settings } from '$lib/stores';
import Modal from '$lib/components/common/Modal.svelte'; import Modal from '$lib/components/common/Modal.svelte';
import Plus from '$lib/components/icons/Plus.svelte'; import Plus from '$lib/components/icons/Plus.svelte';
import Minus from '$lib/components/icons/Minus.svelte'; import Minus from '$lib/components/icons/Minus.svelte';
@ -153,15 +154,16 @@
<Modal size="sm" bind:show> <Modal size="sm" bind:show>
<div> <div>
<div class=" flex justify-between dark:text-gray-100 px-5 pt-4 pb-2"> <div class=" flex justify-between dark:text-gray-100 px-5 pt-4 pb-2">
<div class=" text-lg font-medium self-center font-primary"> <h1 class=" text-lg font-medium self-center font-primary">
{#if edit} {#if edit}
{$i18n.t('Edit Connection')} {$i18n.t('Edit Connection')}
{:else} {:else}
{$i18n.t('Add Connection')} {$i18n.t('Add Connection')}
{/if} {/if}
</div> </h1>
<button <button
class="self-center" class="self-center"
aria-label={$i18n.t('Close Configure Connection Modal')}
on:click={() => { on:click={() => {
show = false; show = false;
}} }}
@ -170,6 +172,7 @@
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20" viewBox="0 0 20 20"
fill="currentColor" fill="currentColor"
aria-hidden="true"
class="w-5 h-5" class="w-5 h-5"
> >
<path <path
@ -192,12 +195,17 @@
<div class="flex gap-2"> <div class="flex gap-2">
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class="flex justify-between mb-0.5"> <div class="flex justify-between mb-0.5">
<div class=" text-xs text-gray-500">{$i18n.t('URL')}</div> <label
for="api-base-url"
class={`text-xs ${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : 'text-gray-500'}`}
>{$i18n.t('URL')}</label
>
</div> </div>
<div class="flex flex-1 items-center"> <div class="flex flex-1 items-center">
<input <input
class="w-full flex-1 text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden" id="api-base-url"
class={`w-full flex-1 text-sm bg-transparent ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
type="text" type="text"
bind:value={url} bind:value={url}
placeholder={$i18n.t('API Base URL')} placeholder={$i18n.t('API Base URL')}
@ -214,6 +222,7 @@
on:click={() => { on:click={() => {
verifyHandler(); verifyHandler();
}} }}
aria-label={$i18n.t('Verify Connection')}
type="button" type="button"
> >
<svg <svg
@ -221,6 +230,7 @@
viewBox="0 0 20 20" viewBox="0 0 20 20"
fill="currentColor" fill="currentColor"
class="w-4 h-4" class="w-4 h-4"
aria-hidden="true"
> >
<path <path
fill-rule="evenodd" fill-rule="evenodd"
@ -237,9 +247,13 @@
</div> </div>
<div class="flex-1 flex items-center"> <div class="flex-1 flex items-center">
<label for="url-or-path" class="sr-only"
>{$i18n.t('openapi.json URL or Path')}</label
>
<input <input
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden" class={`w-full text-sm bg-transparent ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
type="text" type="text"
id="url-or-path"
bind:value={path} bind:value={path}
placeholder={$i18n.t('openapi.json URL or Path')} placeholder={$i18n.t('openapi.json URL or Path')}
autocomplete="off" autocomplete="off"
@ -249,7 +263,9 @@
</div> </div>
</div> </div>
<div class="text-xs text-gray-500 mt-1"> <div
class={`text-xs mt-1 ${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : 'text-gray-500'}`}
>
{$i18n.t(`WebUI will make requests to "{{url}}"`, { {$i18n.t(`WebUI will make requests to "{{url}}"`, {
url: path.includes('://') ? path : `${url}${path.startsWith('/') ? '' : '/'}${path}` url: path.includes('://') ? path : `${url}${path.startsWith('/') ? '' : '/'}${path}`
})} })}
@ -257,12 +273,17 @@
<div class="flex gap-2 mt-2"> <div class="flex gap-2 mt-2">
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class=" text-xs text-gray-500">{$i18n.t('Auth')}</div> <label
for="select-bearer-or-session"
class={`text-xs ${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : 'text-gray-500'}`}
>{$i18n.t('Auth')}</label
>
<div class="flex gap-2"> <div class="flex gap-2">
<div class="flex-shrink-0 self-start"> <div class="flex-shrink-0 self-start">
<select <select
class="w-full text-sm bg-transparent dark:bg-gray-900 placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden pr-5" id="select-bearer-or-session"
class={`w-full text-sm bg-transparent pr-5 ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
bind:value={auth_type} bind:value={auth_type}
> >
<option value="bearer">Bearer</option> <option value="bearer">Bearer</option>
@ -273,13 +294,14 @@
<div class="flex flex-1 items-center"> <div class="flex flex-1 items-center">
{#if auth_type === 'bearer'} {#if auth_type === 'bearer'}
<SensitiveInput <SensitiveInput
className="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
bind:value={key} bind:value={key}
placeholder={$i18n.t('API Key')} placeholder={$i18n.t('API Key')}
required={false} required={false}
/> />
{:else if auth_type === 'session'} {:else if auth_type === 'session'}
<div class="text-xs text-gray-500 self-center translate-y-[1px]"> <div
class={`text-xs self-center translate-y-[1px] ${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : 'text-gray-500'}`}
>
{$i18n.t('Forwards system user session credentials to authenticate')} {$i18n.t('Forwards system user session credentials to authenticate')}
</div> </div>
{/if} {/if}
@ -293,11 +315,16 @@
<div class="flex gap-2"> <div class="flex gap-2">
<div class="flex flex-col w-full"> <div class="flex flex-col w-full">
<div class=" mb-0.5 text-xs text-gray-500">{$i18n.t('Name')}</div> <label
for="enter-name"
class={`mb-0.5 text-xs" ${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : 'text-gray-500'}`}
>{$i18n.t('Name')}</label
>
<div class="flex-1"> <div class="flex-1">
<input <input
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden" id="enter-name"
class={`w-full text-sm bg-transparent ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
type="text" type="text"
bind:value={name} bind:value={name}
placeholder={$i18n.t('Enter name')} placeholder={$i18n.t('Enter name')}
@ -309,11 +336,16 @@
</div> </div>
<div class="flex flex-col w-full mt-2"> <div class="flex flex-col w-full mt-2">
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Description')}</div> <label
for="description"
class={`mb-1 text-xs ${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100 placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700 text-gray-500'}`}
>{$i18n.t('Description')}</label
>
<div class="flex-1"> <div class="flex-1">
<input <input
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden" id="description"
class={`w-full text-sm bg-transparent ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
type="text" type="text"
bind:value={description} bind:value={description}
placeholder={$i18n.t('Enter description')} placeholder={$i18n.t('Enter description')}
@ -358,6 +390,7 @@
{#if loading} {#if loading}
<div class="ml-2 self-center"> <div class="ml-2 self-center">
<svg <svg
aria-hidden="true"
class=" w-4 h-4" class=" w-4 h-4"
viewBox="0 0 24 24" viewBox="0 0 24 24"
fill="currentColor" fill="currentColor"

View File

@ -7,8 +7,7 @@
export let required = true; export let required = true;
export let readOnly = false; export let readOnly = false;
export let outerClassName = 'flex flex-1 bg-transparent'; export let outerClassName = 'flex flex-1 bg-transparent';
export let inputClassName = export let inputClassName = 'w-full text-sm py-0.5 bg-transparent';
'w-full text-sm py-0.5 placeholder:text-gray-300 dark:placeholder:text-gray-700 bg-transparent outline-hidden';
export let showButtonClassName = 'pl-1.5 transition bg-transparent'; export let showButtonClassName = 'pl-1.5 transition bg-transparent';
let show = false; let show = false;
@ -17,7 +16,7 @@
<div class={outerClassName}> <div class={outerClassName}>
<label class="sr-only" for="password-input">{placeholder || $i18n.t('Password')}</label> <label class="sr-only" for="password-input">{placeholder || $i18n.t('Password')}</label>
<input <input
class={`${inputClassName} ${show ? '' : 'password'} ${($settings?.highContrastMode ?? false) ? '' : ' outline-hidden'}`} class={`${inputClassName} ${show ? '' : 'password'} ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : ' outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
{placeholder} {placeholder}
id="password-input" id="password-input"
bind:value bind:value

View File

@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher, tick } from 'svelte'; import { createEventDispatcher, tick } from 'svelte';
import { Switch } from 'bits-ui'; import { Switch } from 'bits-ui';
import { settings } from '$lib/stores';
export let state = true; export let state = true;
export let id = ''; export let id = '';
@ -12,9 +13,12 @@
<Switch.Root <Switch.Root
bind:checked={state} bind:checked={state}
{id} {id}
class="flex h-5 min-h-5 w-9 shrink-0 cursor-pointer items-center rounded-full px-[3px] mx-[1px] transition {state class="flex h-5 min-h-5 w-9 shrink-0 cursor-pointer items-center rounded-full px-[3px] mx-[1px] transition {($settings?.highContrastMode ??
false)
? 'focus:outline focus:outline-2 focus:outline-gray-800 focus:dark:outline-gray-200'
: 'outline outline-1 outline-gray-100 dark:outline-gray-800'} {state
? ' bg-emerald-600' ? ' bg-emerald-600'
: 'bg-gray-200 dark:bg-transparent'} outline outline-1 outline-gray-100 dark:outline-gray-800" : 'bg-gray-200 dark:bg-transparent'}"
> >
<Switch.Thumb <Switch.Thumb
class="pointer-events-none block size-4 shrink-0 rounded-full bg-white transition-transform data-[state=checked]:translate-x-3.5 data-[state=unchecked]:translate-x-0 data-[state=unchecked]:shadow-mini " class="pointer-events-none block size-4 shrink-0 rounded-full bg-white transition-transform data-[state=checked]:translate-x-3.5 data-[state=unchecked]:translate-x-0 data-[state=unchecked]:shadow-mini "