open-webui/src/lib/components/common/Switch.svelte
davecrab 7762fa5ddf
feat: Add adjustable text size setting to interface (#19186)
* Add adjustable text size setting to interface

Introduces a user-configurable text size (scale) setting, accessible via a slider in the interface settings. Updates CSS and Sidebar chat item components to respect the new --app-text-scale variable, and persists the setting in the store. Adds related i18n strings and ensures the text scale is applied globally and clamped to allowed values.

* Refactor text scale logic into utility module

Moved all text scale related constants and functions from components and stores into a new utility module (src/lib/utils/text-scale.ts). Updated imports and usage in Interface.svelte and index.ts to use the new module, improving code organization and reusability.

* Adjust sidebar chat scaling without extra classes

keep sidebar markup using existing Tailwind utility classes so chat items render identically pre-feature
move all text-scale sizing into app.css under the #sidebar-chat-item selectors
change the root font-size multiplier to use 1rem instead of an explicit 16px so browser/user preferences propagate

* Update Switch.svelte

Adjust toggles from fixed pixel to rem to scale with the text size

* Update Interface.svelte

Updated label from 'Text Scale' to 'UI Scale'.
Added padding around slider

* Update app.css

Added comments
2025-11-19 00:55:52 -05:00

46 lines
1.4 KiB
Svelte

<script lang="ts">
import { Switch } from 'bits-ui';
import { createEventDispatcher, tick, getContext } from 'svelte';
import { settings } from '$lib/stores';
import Tooltip from './Tooltip.svelte';
export let state = true;
export let id = '';
export let ariaLabelledbyId = '';
export let tooltip = false;
const i18n = getContext('i18n');
const dispatch = createEventDispatcher();
</script>
<Tooltip
content={typeof tooltip === 'string'
? tooltip
: typeof tooltip === 'boolean' && tooltip
? state
? $i18n.t('Enabled')
: $i18n.t('Disabled')
: ''}
placement="top"
>
<Switch.Root
bind:checked={state}
{id}
aria-labelledby={ariaLabelledbyId}
class="flex h-[1.125rem] min-h-[1.125rem] w-8 shrink-0 cursor-pointer items-center rounded-full px-1 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-500 dark:bg-emerald-700'
: 'bg-gray-200 dark:bg-transparent'}"
onCheckedChange={async () => {
await tick();
dispatch('change', state);
}}
>
<Switch.Thumb
class="pointer-events-none block size-3 shrink-0 rounded-full bg-white transition-transform data-[state=checked]:translate-x-3 data-[state=unchecked]:translate-x-0 data-[state=unchecked]:shadow-mini "
/>
</Switch.Root>
</Tooltip>