🔨 refactor: 重构基于 svelte 的设置面板功能

This commit is contained in:
frostime 2024-06-08 18:30:53 +08:00
parent 49eb06330d
commit 6d75a46a56
6 changed files with 187 additions and 119 deletions

2
src/libs/index.d.ts vendored
View file

@ -28,12 +28,12 @@ interface ISettingItemCore {
interface ISettingItem extends ISettingItemCore { interface ISettingItem extends ISettingItemCore {
title: string; title: string;
description: string; description: string;
direction?: "row" | "column";
} }
//Interface for setting-utils //Interface for setting-utils
interface ISettingUtilsItem extends ISettingItem { interface ISettingUtilsItem extends ISettingItem {
direction?: "row" | "column";
action?: { action?: {
callback: () => void; callback: () => void;
} }

108
src/libs/item-input.svelte Normal file
View file

@ -0,0 +1,108 @@
<!--
Copyright (c) 2024 by frostime. All Rights Reserved.
Author : frostime
Date : 2024-06-07 18:49:52
FilePath : /src/libs/components/input-item.svelte
LastEditTime : 2024-06-07 20:07:58
Description :
-->
<script lang="ts">
import { createEventDispatcher } from "svelte";
export let type: string; // Setting Type
export let key: string;
export let value: any;
//Optional
export let placeholder: string = "";
export let options: { [key: string | number]: string } = {};
export let slider: {
min: number;
max: number;
step: number;
} = { min: 0, max: 100, step: 1 };
export let button: {
label: string;
callback?: () => void;
} = { label: value, callback: () => {} };
const dispatch = createEventDispatcher();
function click() {
button?.callback();
dispatch("click", { key: key });
}
function changed() {
dispatch("changed", { key: key, value: value });
}
</script>
{#if type === "checkbox"}
<!-- Checkbox -->
<input
class="b3-switch fn__flex-center"
id={key}
type="checkbox"
bind:checked={value}
on:change={changed}
/>
{:else if type === "textinput"}
<!-- Text Input -->
<input
class="b3-text-field fn__flex-center fn__size200"
id={key}
{placeholder}
bind:value={value}
on:change={changed}
/>
{:else if type === "textarea"}
<textarea
class="b3-text-field fn__block"
style="resize: vertical; height: 10em; white-space: nowrap;"
bind:value={value}
on:change={changed}
/>
{:else if type === "number"}
<input
class="b3-text-field fn__flex-center fn__size200"
id={key}
type="number"
bind:value={value}
on:change={changed}
/>
{:else if type === "button"}
<!-- Button Input -->
<button
class="b3-button b3-button--outline fn__flex-center fn__size200"
id={key}
on:click={click}
>
{button.label}
</button>
{:else if type === "select"}
<!-- Dropdown select -->
<select
class="b3-select fn__flex-center fn__size200"
id="iconPosition"
bind:value={value}
on:change={changed}
>
{#each Object.entries(options) as [value, text]}
<option {value}>{text}</option>
{/each}
</select>
{:else if type == "slider"}
<!-- Slider -->
<div class="b3-tooltips b3-tooltips__n" aria-label={value}>
<input
class="b3-slider fn__size200"
id="fontSize"
min={slider.min}
max={slider.max}
step={slider.step}
type="range"
bind:value={value}
on:change={changed}
/>
</div>
{/if}

51
src/libs/item-wrap.svelte Normal file
View file

@ -0,0 +1,51 @@
<!--
Copyright (c) 2024 by frostime. All Rights Reserved.
Author : frostime
Date : 2024-06-01 20:03:50
FilePath : /src/libs/setting-item-wrap.svelte
LastEditTime : 2024-06-07 19:14:28
Description : The setting item container
-->
<script lang="ts">
export let title: string; // Displayint Setting Title
export let description: string; // Displaying Setting Text
export let direction: 'row' | 'column' = 'column';
</script>
{#if direction === "row"}
<div class="item-wrap b3-label" data-key="CustomCSS">
<div class="fn__block">
<span class="title">{title}</span>
<div class="b3-label__text">{@html description}</div>
<div class="fn__hr"></div>
<slot />
</div>
</div>
{:else}
<div class="item-wrap fn__flex b3-label config__item">
<div class="fn__flex-1">
<span class="title">{title}</span>
<div class="b3-label__text">
{@html description}
</div>
</div>
<span class="fn__space" />
<slot />
</div>
{/if}
<style>
span.title {
font-weight: bold;
color: var(--b3-theme-primary)
}
.item-wrap.b3-label {
box-shadow: none !important;
padding-bottom: 16px;
margin-bottom: 16px;
}
.item-wrap.b3-label:not(:last-child) {
border-bottom: 1px solid var(--b3-border-color);
}
</style>

View file

@ -1,105 +0,0 @@
<script lang="ts">
import { createEventDispatcher } from "svelte";
export let type: string; // Setting Type
export let title: string; // Displayint Setting Title
export let description: string; // Displaying Setting Text
export let settingKey: string;
export let settingValue: any;
//Optional
export let placeholder: string = ""; // Use it if type is input
export let options: { [key: string | number]: string } = {}; // Use it if type is select
export let slider: {
min: number;
max: number;
step: number;
} = { min: 0, max: 100, step: 1 }; // Use it if type is slider
export let button: {
label: string;
callback: () => void;
} = { label: settingValue, callback: () => {} }; // Use it if type is button
const dispatch = createEventDispatcher();
function click() {
button?.callback();
dispatch("click", { key: settingKey });
}
function changed() {
dispatch("changed", { key: settingKey, value: settingValue });
}
</script>
<label class="fn__flex b3-label">
<div class="fn__flex-1">
{title}
<div class="b3-label__text">
{@html description}
</div>
</div>
<span class="fn__space" />
<!-- <slot /> -->
{#if type === "checkbox"}
<!-- Checkbox -->
<input
class="b3-switch fn__flex-center"
id={settingKey}
type="checkbox"
bind:checked={settingValue}
on:change={changed}
/>
{:else if type === "textinput"}
<!-- Text Input -->
<input
class="b3-text-field fn__flex-center fn__size200"
id={settingKey}
{placeholder}
bind:value={settingValue}
on:change={changed}
/>
{:else if type === "number"}
<input
class="b3-text-field fn__flex-center fn__size200"
id={settingKey}
type="number"
bind:value={settingValue}
on:change={changed}
/>
{:else if type === "button"}
<!-- Button Input -->
<button
class="b3-button b3-button--outline fn__flex-center fn__size200"
id={settingKey}
on:click={click}
>
{button.label}
</button>
{:else if type === "select"}
<!-- Dropdown select -->
<select
class="b3-select fn__flex-center fn__size200"
id="iconPosition"
bind:value={settingValue}
on:change={changed}
>
{#each Object.entries(options) as [value, text]}
<option {value}>{text}</option>
{/each}
</select>
{:else if type == "slider"}
<!-- Slider -->
<div class="b3-tooltips b3-tooltips__n" aria-label={settingValue}>
<input
class="b3-slider fn__size200"
id="fontSize"
min={slider.min}
max={slider.max}
step={slider.step}
type="range"
bind:value={settingValue}
on:change={changed}
/>
</div>
{/if}
</label>

View file

@ -3,12 +3,13 @@
Author : frostime Author : frostime
Date : 2023-07-01 19:23:50 Date : 2023-07-01 19:23:50
FilePath : /src/libs/setting-panel.svelte FilePath : /src/libs/setting-panel.svelte
LastEditTime : 2024-04-27 16:46:49 LastEditTime : 2024-06-08 18:25:34
Description : Description :
--> -->
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import SettingItem from "./setting-item.svelte"; import ItemWrap from "./item-wrap.svelte";
import InputItem from "./item-input.svelte";
export let group: string; export let group: string;
export let settingItems: ISettingItem[]; export let settingItems: ISettingItem[];
@ -30,18 +31,22 @@
<div class="config__tab-container {fn__none}" data-name={group}> <div class="config__tab-container {fn__none}" data-name={group}>
<slot /> <slot />
{#each settingItems as item (item.key)} {#each settingItems as item (item.key)}
<SettingItem <ItemWrap
type={item.type}
title={item.title} title={item.title}
description={item.description} description={item.description}
settingKey={item.key} direction={item?.direction}
settingValue={item.value} >
placeholder={item?.placeholder} <InputItem
options={item?.options} type={item.type}
slider={item?.slider} key={item.key}
button={item?.button} bind:value={item.value}
on:click={onClick} placeholder={item?.placeholder}
on:changed={onChanged} options={item?.options}
/> slider={item?.slider}
button={item?.button}
on:click={onClick}
on:changed={onChanged}
/>
</ItemWrap>
{/each} {/each}
</div> </div>

View file

@ -21,6 +21,15 @@
value: 'This is a text', value: 'This is a text',
placeholder: 'placeholder' placeholder: 'placeholder'
}, },
{
type: 'textarea',
title: 'textarea',
description: 'This is a textarea',
key: 'b2',
value: 'This is a textarea',
placeholder: 'placeholder',
direction: 'row'
},
{ {
type: 'select', type: 'select',
title: 'select', title: 'select',