mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
style: major interface improvements
This commit is contained in:
@@ -2,6 +2,6 @@
|
||||
let { onClick, text } = $props<{ onClick: () => void, text: string, [key: string]: any }>();
|
||||
</script>
|
||||
|
||||
<button onclick={onClick} class='px-4 py-1 text-[0.75rem] dark:bg-[#38373D] bg-[#DDDDDD] dark:text-white rounded-md'>
|
||||
<button onclick={onClick} class='px-5 py-1.5 text-[0.75rem] bg-gradient-to-tr dark:from-[#38373D] dark:to-[#38373D]/80 from-[#DDDDDD] to-[#DDDDDD]/80 dark:text-white rounded-lg'>
|
||||
{text}
|
||||
</button>
|
||||
@@ -8,15 +8,17 @@
|
||||
let select: HTMLSelectElement;
|
||||
</script>
|
||||
|
||||
<select
|
||||
bind:this={select}
|
||||
value={state}
|
||||
onchange={() => onChange(select.value)}
|
||||
class="px-4 py-1 text-[0.75rem] dark:bg-[#38373D] bg-[#DDDDDD] dark:text-white rounded-md w-full"
|
||||
>
|
||||
{#each options as option}
|
||||
<option value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
<div class="bg-gradient-to-tr dark:to-[#38373D]/80 dark:from-[#38373D]/90 from-[#DDDDDD] to-[#DDDDDD]/80 rounded-lg w-full overflow-clip">
|
||||
<select
|
||||
bind:this={select}
|
||||
value={state}
|
||||
onchange={() => onChange(select.value)}
|
||||
class="px-4 py-1 text-[0.75rem] dark:text-white w-full border-none bg-transparent focus:ring-0 focus:bg-white/20 dark:focus:bg-black/10"
|
||||
>
|
||||
{#each options as option}
|
||||
<option value={option.value}>
|
||||
{option.label}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
max={max}
|
||||
step={step}
|
||||
bind:value={state}
|
||||
style={`background: linear-gradient(to right, #30D259 ${percentage}%, #dddddd ${percentage}%)`}
|
||||
style={`background: linear-gradient(to right, #30d259ad 0%, #30D259 ${percentage}%, #dddddd ${percentage}%)`}
|
||||
onchange={(e) => onChange(Number(e.currentTarget.value))}
|
||||
class="w-full h-1 rounded-full appearance-none cursor-pointer dark:bg-[#38373D] bg-[#DDDDDD] slider"
|
||||
class="w-full h-1 rounded-full appearance-none cursor-pointer slider"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
height: 24px;
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.3);
|
||||
background: white;
|
||||
color: #30d259ad;
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex w-14 p-1 cursor-pointer transition-all duration-150 rounded-full dark:bg-[#38373D] bg-[#DDDDDD] switch select-none"
|
||||
class="flex w-14 p-1 cursor-pointer transition-all duration-150 rounded-full bg-gradient-to-tr dark:from-[#38373D]/50 dark:to-[#38373D] from-[#DDDDDD]/50 to-[#DDDDDD] switch select-none"
|
||||
data-ison={state}
|
||||
onclick={() => onChange(!state)}
|
||||
onkeydown={(e) => e.key === "Enter" && onChange(!state)}
|
||||
@@ -46,6 +46,6 @@
|
||||
|
||||
<style>
|
||||
.switch[data-ison="true"] {
|
||||
background-color: #30D259;
|
||||
@apply from-[#30D259]/50 to-[#30D259];
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<div class="top-0 z-10 text-[0.875rem] pb-0.5 mx-4 px-2 tab-width-container">
|
||||
<div bind:this={containerRef} class="flex relative">
|
||||
<MotionDiv
|
||||
class="absolute top-0 left-0 z-0 h-full bg-[#DDDDDD] dark:bg-[#38373D] rounded-full opacity-40 tab-width"
|
||||
class="absolute top-0 left-0 z-0 h-full bg-gradient-to-tr dark:from-[#38373D]/80 dark:to-[#38373D] from-[#DDDDDD]/80 to-[#DDDDDD] rounded-full opacity-40 tab-width"
|
||||
animate={{ x: calcXPos(activeTab) }}
|
||||
transition={springTransition}
|
||||
/>
|
||||
@@ -65,8 +65,9 @@
|
||||
>
|
||||
<div class="flex">
|
||||
{#each tabs as { Content, props }, index}
|
||||
<div class="absolute focus:outline-none w-full transition-opacity duration-300 overflow-y-scroll no-scrollbar h-full tab {activeTab === index ? 'opacity-100 active' : 'opacity-0'}"
|
||||
style="left: {index * 100}%;">
|
||||
<div class="absolute focus:outline-none w-full pt-2 transition-opacity duration-300 overflow-y-scroll no-scrollbar pb-2 h-full tab {activeTab === index ? 'opacity-100 active' : 'opacity-0'}"
|
||||
style="left: {index * 100}%;">
|
||||
<div style="left: {index * 100}%;" class="fixed top-0 w-full h-8 bg-gradient-to-b to-transparent pointer-events-none z-[100] from-zinc-200 dark:from-zinc-800 dark:to-transparent"></div>
|
||||
<Content {...props} />
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
|
||||
<div class="w-[384px] no-scrollbar shadow-2xl {$settingsState.DarkMode ? 'dark' : ''} { standalone ? 'h-[600px]' : 'h-full rounded-xl' } overflow-clip">
|
||||
<div class="flex relative flex-col gap-2 h-full overflow-clip bg-white dark:bg-zinc-800 dark:text-white">
|
||||
<div class="grid place-items-center border-b border-b-zinc-200/40">
|
||||
<div class="grid place-items-center border-b border-b-zinc-200/40 dark:border-b-zinc-700/40">
|
||||
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
<img src={browser.runtime.getURL('resources/icons/betterseqta-dark-full.png')} class="w-4/5 dark:hidden" alt="Light logo" onclick={handleDevModeToggle} />
|
||||
|
||||
@@ -184,71 +184,75 @@
|
||||
{/each}
|
||||
|
||||
{#each pluginSettings as plugin}
|
||||
<div class="p-1 my-1 bg-white rounded-xl border shadow-sm border-zinc-200 dark:border-zinc-700 dark:bg-zinc-900/50 {!(plugin as any).disableToggle && Object.keys(plugin.settings).length === 0 ? 'hidden' : ''}">
|
||||
<!-- Always show enable toggle if disableToggle is true -->
|
||||
{#if (plugin as any).disableToggle}
|
||||
<div class="flex justify-between items-center px-4 py-3">
|
||||
<div class="pr-4">
|
||||
<h2 class="text-sm font-bold">Enable {plugin.name}</h2>
|
||||
<p class="text-xs">{plugin.description}</p>
|
||||
</div>
|
||||
<div>
|
||||
<Switch
|
||||
state={pluginSettingsValues[plugin.pluginId]?.enabled ?? true}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, 'enabled', value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !((plugin as any).disableToggle) || (pluginSettingsValues[plugin.pluginId]?.enabled ?? true)}
|
||||
{#each Object.entries(plugin.settings) as [key, setting]}
|
||||
<!-- Skip the 'enabled' setting if it's part of the settings object -->
|
||||
{#if key !== 'enabled'}
|
||||
<div class="flex justify-between items-center px-4 py-3">
|
||||
<div class="pr-4">
|
||||
<h2 class="text-sm font-bold">{setting.title || key}</h2>
|
||||
<p class="text-xs">{setting.description || ''}</p>
|
||||
</div>
|
||||
<div>
|
||||
{#if setting.type === 'boolean'}
|
||||
<Switch
|
||||
state={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, key, value)}
|
||||
/>
|
||||
{:else if setting.type === 'number'}
|
||||
<Slider
|
||||
state={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, key, value)}
|
||||
min={setting.min}
|
||||
max={setting.max}
|
||||
step={setting.step}
|
||||
/>
|
||||
{:else if setting.type === 'string'}
|
||||
<input
|
||||
type="text"
|
||||
class="px-2 py-1 text-sm rounded-md dark:bg-[#38373D] bg-[#DDDDDD] dark:text-white"
|
||||
value={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
oninput={(e) => updatePluginSetting(plugin.pluginId, key, e.currentTarget.value)}
|
||||
/>
|
||||
{:else if setting.type === 'select'}
|
||||
<Select
|
||||
state={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, key, value)}
|
||||
options={(setting.options as string[]).map(opt => ({
|
||||
value: opt,
|
||||
label: opt.charAt(0).toUpperCase() + opt.slice(1)
|
||||
}))}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="border-none">
|
||||
<div class="p-1 my-1 from-white to-zinc-100 bg-gradient-to-br rounded-xl border shadow-sm border-zinc-200/50 dark:border-zinc-700/40 dark:to-zinc-900/50 dark:from-zinc-900/40 {!(plugin as any).disableToggle && Object.keys(plugin.settings).length === 0 ? 'hidden' : ''}">
|
||||
<!-- Always show enable toggle if disableToggle is true -->
|
||||
{#if (plugin as any).disableToggle}
|
||||
<div class="flex justify-between items-center px-4 py-3">
|
||||
<div class="pr-4">
|
||||
<h2 class="text-sm font-bold">Enable {plugin.name}</h2>
|
||||
<p class="text-xs">{plugin.description}</p>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<Switch
|
||||
state={pluginSettingsValues[plugin.pluginId]?.enabled ?? true}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, 'enabled', value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !((plugin as any).disableToggle) || (pluginSettingsValues[plugin.pluginId]?.enabled ?? true)}
|
||||
{#each Object.entries(plugin.settings) as [key, setting]}
|
||||
<!-- Skip the 'enabled' setting if it's part of the settings object -->
|
||||
{#if key !== 'enabled'}
|
||||
<div class="flex justify-between items-center px-4 py-3">
|
||||
<div class="pr-4">
|
||||
<h2 class="text-sm font-bold">{setting.title || key}</h2>
|
||||
<p class="text-xs">{setting.description || ''}</p>
|
||||
</div>
|
||||
<div>
|
||||
{#if setting.type === 'boolean'}
|
||||
<Switch
|
||||
state={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, key, value)}
|
||||
/>
|
||||
{:else if setting.type === 'number'}
|
||||
<Slider
|
||||
state={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, key, value)}
|
||||
min={setting.min}
|
||||
max={setting.max}
|
||||
step={setting.step}
|
||||
/>
|
||||
{:else if setting.type === 'string'}
|
||||
<input
|
||||
type="text"
|
||||
class="px-2 py-1 text-sm rounded-md dark:bg-[#38373D]/50 bg-[#DDDDDD] dark:text-white border-none"
|
||||
value={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
oninput={(e) => updatePluginSetting(plugin.pluginId, key, e.currentTarget.value)}
|
||||
/>
|
||||
{:else if setting.type === 'select'}
|
||||
<Select
|
||||
state={pluginSettingsValues[plugin.pluginId]?.[key] ?? setting.default}
|
||||
onChange={(value) => updatePluginSetting(plugin.pluginId, key, value)}
|
||||
options={(setting.options as string[]).map(opt => ({
|
||||
value: opt,
|
||||
label: opt.charAt(0).toUpperCase() + opt.slice(1)
|
||||
}))}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
<div class="p-1 border-none"></div>
|
||||
|
||||
{@render Setting({
|
||||
title: "BetterSEQTA+",
|
||||
description: "Enables BetterSEQTA+ features",
|
||||
|
||||
@@ -3,17 +3,19 @@
|
||||
import type { DynamicContentItem } from '../../utils/dynamicItems';
|
||||
import type { FuseResultMatch } from '../../core/types';
|
||||
|
||||
const { item, isSelected, searchTerm, matches } = $props<{
|
||||
const { item, isSelected, searchTerm, matches, onclick } = $props<{
|
||||
item: DynamicContentItem;
|
||||
isSelected: boolean;
|
||||
searchTerm: string;
|
||||
matches?: readonly FuseResultMatch[];
|
||||
onclick: () => void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<button
|
||||
class="w-full flex flex-col px-2 py-1.5 rounded-lg select-none cursor-pointer group transition-colors duration-100
|
||||
{isSelected ? 'bg-zinc-900/5 dark:bg-white/10 text-zinc-900 dark:text-white' : 'hover:bg-zinc-500/5 dark:hover:bg-white/5 text-zinc-800 dark:text-zinc-200'}"
|
||||
onclick={onclick}
|
||||
>
|
||||
<div class="flex items-center w-full">
|
||||
<div class="flex-none w-8 h-8 text-xl font-IconFamily flex items-center justify-center {isSelected ? 'text-zinc-900 dark:text-white' : 'text-zinc-600 dark:text-zinc-400'}">{item.metadata?.icon || '\uebee'}</div>
|
||||
|
||||
@@ -3,17 +3,19 @@
|
||||
import type { DynamicContentItem } from '../../utils/dynamicItems';
|
||||
import type { FuseResultMatch } from '../../core/types';
|
||||
|
||||
const { item, isSelected, searchTerm, matches } = $props<{
|
||||
const { item, isSelected, searchTerm, matches, onclick } = $props<{
|
||||
item: DynamicContentItem;
|
||||
isSelected: boolean;
|
||||
searchTerm: string;
|
||||
matches?: readonly FuseResultMatch[];
|
||||
onclick: () => void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<button
|
||||
class="w-full flex flex-col px-2 py-1.5 rounded-lg select-none cursor-pointer group transition-colors duration-100
|
||||
{isSelected ? 'bg-zinc-900/5 dark:bg-white/10 text-zinc-900 dark:text-white' : 'hover:bg-zinc-500/5 dark:hover:bg-white/5 text-zinc-800 dark:text-zinc-200'}"
|
||||
onclick={onclick}
|
||||
>
|
||||
<div class="flex items-center w-full">
|
||||
<div class="flex-none w-8 h-8 text-xl font-IconFamily flex items-center justify-center {isSelected ? 'text-zinc-900 dark:text-white' : 'text-zinc-600 dark:text-zinc-400'}">{item.metadata?.icon || '\uebe7'}</div>
|
||||
|
||||
Reference in New Issue
Block a user