🔨 refactor: 重构基于 svelte 的设置面板功能
This commit is contained in:
parent
49eb06330d
commit
6d75a46a56
6 changed files with 187 additions and 119 deletions
2
src/libs/index.d.ts
vendored
2
src/libs/index.d.ts
vendored
|
@ -28,12 +28,12 @@ interface ISettingItemCore {
|
|||
interface ISettingItem extends ISettingItemCore {
|
||||
title: string;
|
||||
description: string;
|
||||
direction?: "row" | "column";
|
||||
}
|
||||
|
||||
|
||||
//Interface for setting-utils
|
||||
interface ISettingUtilsItem extends ISettingItem {
|
||||
direction?: "row" | "column";
|
||||
action?: {
|
||||
callback: () => void;
|
||||
}
|
||||
|
|
108
src/libs/item-input.svelte
Normal file
108
src/libs/item-input.svelte
Normal 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
51
src/libs/item-wrap.svelte
Normal 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>
|
|
@ -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>
|
|
@ -3,12 +3,13 @@
|
|||
Author : frostime
|
||||
Date : 2023-07-01 19:23:50
|
||||
FilePath : /src/libs/setting-panel.svelte
|
||||
LastEditTime : 2024-04-27 16:46:49
|
||||
LastEditTime : 2024-06-08 18:25:34
|
||||
Description :
|
||||
-->
|
||||
<script lang="ts">
|
||||
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 settingItems: ISettingItem[];
|
||||
|
@ -30,12 +31,15 @@
|
|||
<div class="config__tab-container {fn__none}" data-name={group}>
|
||||
<slot />
|
||||
{#each settingItems as item (item.key)}
|
||||
<SettingItem
|
||||
type={item.type}
|
||||
<ItemWrap
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
settingKey={item.key}
|
||||
settingValue={item.value}
|
||||
direction={item?.direction}
|
||||
>
|
||||
<InputItem
|
||||
type={item.type}
|
||||
key={item.key}
|
||||
bind:value={item.value}
|
||||
placeholder={item?.placeholder}
|
||||
options={item?.options}
|
||||
slider={item?.slider}
|
||||
|
@ -43,5 +47,6 @@
|
|||
on:click={onClick}
|
||||
on:changed={onChanged}
|
||||
/>
|
||||
</ItemWrap>
|
||||
{/each}
|
||||
</div>
|
|
@ -21,6 +21,15 @@
|
|||
value: 'This is a text',
|
||||
placeholder: 'placeholder'
|
||||
},
|
||||
{
|
||||
type: 'textarea',
|
||||
title: 'textarea',
|
||||
description: 'This is a textarea',
|
||||
key: 'b2',
|
||||
value: 'This is a textarea',
|
||||
placeholder: 'placeholder',
|
||||
direction: 'row'
|
||||
},
|
||||
{
|
||||
type: 'select',
|
||||
title: 'select',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue