refactor: 提取通用的 TextInput 输入框组件并在后台页面中统一替换
continuous-integration/drone/push Build is passing

This commit is contained in:
seahi committed 2026-08-15 14:50:25 +08:00
1 parent 40ffee0c91
commit 45fe86cbbb
9 files changed
+136 -264

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
<script lang="ts">
import type { HTMLInputAttributes } from 'svelte/elements';
interface Props extends Omit<HTMLInputAttributes, 'size'> {
variant?: 'underline' | 'solid';
size?: 'sm' | 'md';
value?: string | number | string[] | undefined | null;
}
let {
variant = 'solid',
size = 'md',
value = $bindable(),
class: className = '',
...rest
}: Props = $props();
</script>
<input class="admin-input {variant} size-{size} {className}" bind:value {...rest} />
<style>
.admin-input {
width: 100%;
font-family: inherit;
color: var(--text-color);
box-sizing: border-box;
}
.admin-input:focus {
outline: none;
}
/* variant: underline */
.admin-input.underline {
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
transition: border-bottom-color 0.3s ease;
}
.admin-input.underline:focus {
border-bottom-color: var(--accent-color, #419b38);
}
/* variant: solid */
.admin-input.solid {
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 0;
background: rgba(0, 0, 0, 0.015);
transition:
border-color 0.3s ease,
box-shadow 0.3s ease;
}
.admin-input.solid:focus {
border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
}
/* size: md (default for main forms) */
.admin-input.size-md {
padding: 12px 14px;
font-size: 1.05rem;
}
/* override padding for underline which traditionally uses less padding */
.admin-input.underline.size-md {
padding: 10px 0;
}
/* size: sm (default for tables / sidebars) */
.admin-input.size-sm {
padding: 8px 10px;
font-size: 0.95rem;
}
.admin-input.underline.size-sm {
padding: 8px 0;
}
</style>
+9 -45
View File
@@ -3,6 +3,7 @@
import type { PageData, ActionData } from './$types'; import type { PageData, ActionData } from './$types';
import { createSlugAutoHandler } from '$lib/utils/slugify'; import { createSlugAutoHandler } from '$lib/utils/slugify';
import { confirmState } from '$lib/stores/confirm.svelte'; import { confirmState } from '$lib/stores/confirm.svelte';
import TextInput from '$lib/components/admin/TextInput.svelte';
let { data, form }: { data: PageData; form: ActionData } = $props(); let { data, form }: { data: PageData; form: ActionData } = $props();
@@ -47,7 +48,7 @@
<form method="POST" action="?/create"> <form method="POST" action="?/create">
<div class="form-group"> <div class="form-group">
<label for="name">名称 *</label> <label for="name">名称 *</label>
<input <TextInput
type="text" type="text"
id="name" id="name"
name="name" name="name"
@@ -55,6 +56,7 @@
oninput={handleNameInput} oninput={handleNameInput}
placeholder="例如: 技术分享" placeholder="例如: 技术分享"
required required
variant="underline"
/> />
</div> </div>
<div class="form-group"> <div class="form-group">
@@ -72,13 +74,14 @@
{isGenerating ? '正在生成...' : '重新生成'} {isGenerating ? '正在生成...' : '重新生成'}
</button> </button>
</label> </label>
<input <TextInput
type="text" type="text"
id="slug" id="slug"
name="slug" name="slug"
bind:value={slug} bind:value={slug}
oninput={handleSlugInput} oninput={handleSlugInput}
placeholder="例如: tech-sharing" placeholder="例如: tech-sharing"
variant="underline"
/> />
</div> </div>
<button type="submit" class="btn btn-primary">创建</button> <button type="submit" class="btn btn-primary">创建</button>
@@ -108,13 +111,13 @@
<td>{category.id}</td> <td>{category.id}</td>
<td> <td>
{#if editingId === category.id} {#if editingId === category.id}
<input <TextInput
type="text" type="text"
name="name" name="name"
value={category.name} value={category.name}
form="edit-form-{category.id}" form="edit-form-{category.id}"
required required
class="edit-input" size="sm"
/> />
{:else} {:else}
<strong>{category.name}</strong> <strong>{category.name}</strong>
@@ -122,13 +125,13 @@
</td> </td>
<td> <td>
{#if editingId === category.id} {#if editingId === category.id}
<input <TextInput
type="text" type="text"
name="slug" name="slug"
value={category.slug} value={category.slug}
form="edit-form-{category.id}" form="edit-form-{category.id}"
required required
class="edit-input" size="sm"
/> />
{:else} {:else}
<span class="badge">{category.slug}</span> <span class="badge">{category.slug}</span>
@@ -261,24 +264,6 @@
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
.form-group input[type='text'] {
width: 100%;
padding: 10px 0;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
font-family: inherit;
font-size: 1.05rem;
color: var(--text-color);
box-sizing: border-box;
transition: border-bottom-color 0.3s ease;
}
.form-group input[type='text']:focus {
outline: none;
border-bottom-color: var(--accent-color, #419b38);
}
.btn { .btn {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
@@ -384,25 +369,4 @@
text-align: center; text-align: center;
color: var(--text-muted, rgba(0, 0, 0, 0.6)); color: var(--text-muted, rgba(0, 0, 0, 0.6));
} }
.edit-input {
width: 100%;
padding: 8px 10px;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 0;
background: rgba(0, 0, 0, 0.015);
font-family: inherit;
font-size: 0.95rem;
color: var(--text-color);
box-sizing: border-box;
transition:
border-color 0.3s ease,
box-shadow 0.3s ease;
}
.edit-input:focus {
outline: none;
border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
}
</style> </style>
+4 -23
View File
@@ -3,6 +3,7 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
import type { PageData, ActionData } from './$types'; import type { PageData, ActionData } from './$types';
import MarkdownRenderer from '$lib/components/MarkdownRenderer.svelte'; import MarkdownRenderer from '$lib/components/MarkdownRenderer.svelte';
import TextInput from '$lib/components/admin/TextInput.svelte';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
let { data, form }: { data: PageData; form: ActionData } = $props(); let { data, form }: { data: PageData; form: ActionData } = $props();
@@ -38,7 +39,7 @@
<div class="form-main"> <div class="form-main">
<div class="form-group"> <div class="form-group">
<label for="title">标题 *</label> <label for="title">标题 *</label>
<input <TextInput
type="text" type="text"
id="title" id="title"
name="title" name="title"
@@ -92,14 +93,14 @@
<div class="sidebar-box"> <div class="sidebar-box">
<h3>别名 *</h3> <h3>别名 *</h3>
<input <TextInput
type="text" type="text"
id="slug" id="slug"
name="slug" name="slug"
class="sidebar-input"
bind:value={slug} bind:value={slug}
placeholder="hello-world" placeholder="hello-world"
required required
variant="underline"
/> />
</div> </div>
</div> </div>
@@ -260,7 +261,6 @@
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
.form-group input[type='text'],
.form-group textarea { .form-group textarea {
width: 100%; width: 100%;
padding: 12px 14px; padding: 12px 14px;
@@ -282,31 +282,12 @@
min-height: 120px; min-height: 120px;
} }
.form-group input[type='text']:focus,
.form-group textarea:focus { .form-group textarea:focus {
outline: none; outline: none;
border-color: var(--accent-color, #419b38); border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08); box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
} }
.sidebar-input:focus {
outline: none;
border-bottom-color: var(--accent-color, #419b38);
}
.sidebar-input {
width: 100%;
padding: 10px 0;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
font-family: inherit;
font-size: 1rem;
color: var(--text-color);
box-sizing: border-box;
transition: border-bottom-color 0.3s ease;
}
.sidebar-box { .sidebar-box {
background: transparent; background: transparent;
border: none; border: none;
+4 -23
View File
@@ -3,6 +3,7 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
import type { ActionData } from './$types'; import type { ActionData } from './$types';
import MarkdownRenderer from '$lib/components/MarkdownRenderer.svelte'; import MarkdownRenderer from '$lib/components/MarkdownRenderer.svelte';
import TextInput from '$lib/components/admin/TextInput.svelte';
import { createSlugAutoHandler } from '$lib/utils/slugify'; import { createSlugAutoHandler } from '$lib/utils/slugify';
@@ -48,7 +49,7 @@
<div class="form-main"> <div class="form-main">
<div class="form-group"> <div class="form-group">
<label for="title">标题 *</label> <label for="title">标题 *</label>
<input <TextInput
type="text" type="text"
id="title" id="title"
name="title" name="title"
@@ -113,15 +114,15 @@
{isGenerating ? '正在生成...' : '重新生成'} {isGenerating ? '正在生成...' : '重新生成'}
</button> </button>
</h3> </h3>
<input <TextInput
type="text" type="text"
id="slug" id="slug"
name="slug" name="slug"
class="sidebar-input"
bind:value={slug} bind:value={slug}
oninput={handleSlugInput} oninput={handleSlugInput}
placeholder="about" placeholder="about"
required required
variant="underline"
/> />
</div> </div>
</div> </div>
@@ -277,7 +278,6 @@
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
.form-group input[type='text'],
.form-group textarea { .form-group textarea {
width: 100%; width: 100%;
padding: 12px 14px; padding: 12px 14px;
@@ -299,31 +299,12 @@
min-height: 120px; min-height: 120px;
} }
.form-group input[type='text']:focus,
.form-group textarea:focus { .form-group textarea:focus {
outline: none; outline: none;
border-color: var(--accent-color, #419b38); border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08); box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
} }
.sidebar-input:focus {
outline: none;
border-bottom-color: var(--accent-color, #419b38);
}
.sidebar-input {
width: 100%;
padding: 10px 0;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
font-family: inherit;
font-size: 1rem;
color: var(--text-color);
box-sizing: border-box;
transition: border-bottom-color 0.3s ease;
}
.sidebar-box { .sidebar-box {
background: transparent; background: transparent;
border: none; border: none;
+10 -31
View File
@@ -9,6 +9,7 @@
import FeaturedImagePicker from '$lib/components/admin/FeaturedImagePicker.svelte'; import FeaturedImagePicker from '$lib/components/admin/FeaturedImagePicker.svelte';
import SelectDropdown from '$lib/components/admin/SelectDropdown.svelte'; import SelectDropdown from '$lib/components/admin/SelectDropdown.svelte';
import { parseHugoMarkdown } from '$lib/hugoParser'; import { parseHugoMarkdown } from '$lib/hugoParser';
import TextInput from '$lib/components/admin/TextInput.svelte';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
let { data, form }: { data: PageData; form: ActionData } = $props(); let { data, form }: { data: PageData; form: ActionData } = $props();
@@ -289,7 +290,7 @@
<div class="form-main"> <div class="form-main">
<div class="form-group"> <div class="form-group">
<label for="title">标题 *</label> <label for="title">标题 *</label>
<input <TextInput
type="text" type="text"
id="title" id="title"
name="title" name="title"
@@ -494,14 +495,14 @@
<div class="sidebar-box"> <div class="sidebar-box">
<h3>别名 *</h3> <h3>别名 *</h3>
<input <TextInput
type="text" type="text"
id="slug" id="slug"
name="slug" name="slug"
class="sidebar-input"
bind:value={slug} bind:value={slug}
placeholder="hello-world" placeholder="hello-world"
required required
variant="underline"
/> />
</div> </div>
@@ -526,14 +527,15 @@
options={seriesList.map((series) => ({ value: series.id, label: series.name }))} options={seriesList.map((series) => ({ value: series.id, label: series.name }))}
bind:value={selectedSeriesId} bind:value={selectedSeriesId}
/> />
<input <TextInput
type="number" type="number"
name="series_weight" name="series_weight"
class="sidebar-input series-weight-input" style="margin-top: 10px;"
bind:value={seriesWeight} bind:value={seriesWeight}
placeholder="顺序(留空自动追加)" placeholder="顺序(留空自动追加)"
disabled={!selectedSeriesId} disabled={!selectedSeriesId}
step="1" step="1"
variant="underline"
/> />
</div> </div>
@@ -570,9 +572,9 @@
</div> </div>
<div class="tag-input-container"> <div class="tag-input-container">
<input <TextInput
type="text" type="text"
class="sidebar-input tag-input-new" class="tag-input-new"
placeholder="+ 添加标签..." placeholder="+ 添加标签..."
bind:value={newTagInput} bind:value={newTagInput}
onkeydown={handleAddTag} onkeydown={handleAddTag}
@@ -580,6 +582,7 @@
onblur={() => setTimeout(() => (showTagDropdown = false), 200)} onblur={() => setTimeout(() => (showTagDropdown = false), 200)}
disabled={isAddingTag} disabled={isAddingTag}
autocomplete="off" autocomplete="off"
variant="underline"
/> />
{#if showTagDropdown && filteredTags.length > 0} {#if showTagDropdown && filteredTags.length > 0}
@@ -774,7 +777,6 @@
text-transform: uppercase; text-transform: uppercase;
} }
.form-group input[type='text'],
.form-group textarea { .form-group textarea {
width: 100%; width: 100%;
padding: 12px 14px; padding: 12px 14px;
@@ -796,31 +798,12 @@
min-height: 120px; min-height: 120px;
} }
.form-group input[type='text']:focus,
.form-group textarea:focus { .form-group textarea:focus {
outline: none; outline: none;
border-color: var(--accent-color, #419b38); border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08); box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
} }
.sidebar-input:focus {
outline: none;
border-bottom-color: var(--accent-color, #419b38);
}
.sidebar-input {
width: 100%;
padding: 10px 0;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
font-family: inherit;
font-size: 1rem;
color: var(--text-color);
box-sizing: border-box;
transition: border-bottom-color 0.3s ease;
}
.form-group textarea:focus { .form-group textarea:focus {
outline: none; outline: none;
border-color: var(--accent-color, #419b38); border-color: var(--accent-color, #419b38);
@@ -844,10 +827,6 @@
border-bottom: none; border-bottom: none;
} }
.series-weight-input {
margin-top: 10px;
}
.selected-tags-vertical { .selected-tags-vertical {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
+10 -31
View File
@@ -9,6 +9,7 @@
import FeaturedImagePicker from '$lib/components/admin/FeaturedImagePicker.svelte'; import FeaturedImagePicker from '$lib/components/admin/FeaturedImagePicker.svelte';
import SelectDropdown from '$lib/components/admin/SelectDropdown.svelte'; import SelectDropdown from '$lib/components/admin/SelectDropdown.svelte';
import { parseHugoMarkdown } from '$lib/hugoParser'; import { parseHugoMarkdown } from '$lib/hugoParser';
import TextInput from '$lib/components/admin/TextInput.svelte';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
import { createSlugAutoHandler } from '$lib/utils/slugify'; import { createSlugAutoHandler } from '$lib/utils/slugify';
@@ -306,7 +307,7 @@
<div class="form-main"> <div class="form-main">
<div class="form-group"> <div class="form-group">
<label for="title">标题 *</label> <label for="title">标题 *</label>
<input <TextInput
type="text" type="text"
id="title" id="title"
name="title" name="title"
@@ -524,15 +525,15 @@
{isGenerating ? '正在生成...' : '重新生成'} {isGenerating ? '正在生成...' : '重新生成'}
</button> </button>
</h3> </h3>
<input <TextInput
type="text" type="text"
id="slug" id="slug"
name="slug" name="slug"
class="sidebar-input"
bind:value={slug} bind:value={slug}
oninput={handleSlugInput} oninput={handleSlugInput}
placeholder="hello-world" placeholder="hello-world"
required required
variant="underline"
/> />
</div> </div>
@@ -557,14 +558,15 @@
options={seriesList.map((series) => ({ value: series.id, label: series.name }))} options={seriesList.map((series) => ({ value: series.id, label: series.name }))}
bind:value={selectedSeriesId} bind:value={selectedSeriesId}
/> />
<input <TextInput
type="number" type="number"
name="series_weight" name="series_weight"
class="sidebar-input series-weight-input" style="margin-top: 10px;"
bind:value={seriesWeight} bind:value={seriesWeight}
placeholder="顺序(留空自动追加)" placeholder="顺序(留空自动追加)"
disabled={!selectedSeriesId} disabled={!selectedSeriesId}
step="1" step="1"
variant="underline"
/> />
</div> </div>
@@ -601,9 +603,9 @@
</div> </div>
<div class="tag-input-container"> <div class="tag-input-container">
<input <TextInput
type="text" type="text"
class="sidebar-input tag-input-new" class="tag-input-new"
placeholder="+ 添加标签..." placeholder="+ 添加标签..."
bind:value={newTagInput} bind:value={newTagInput}
onkeydown={handleAddTag} onkeydown={handleAddTag}
@@ -611,6 +613,7 @@
onblur={() => setTimeout(() => (showTagDropdown = false), 200)} onblur={() => setTimeout(() => (showTagDropdown = false), 200)}
disabled={isAddingTag} disabled={isAddingTag}
autocomplete="off" autocomplete="off"
variant="underline"
/> />
{#if showTagDropdown && filteredTags.length > 0} {#if showTagDropdown && filteredTags.length > 0}
@@ -805,7 +808,6 @@
text-transform: uppercase; text-transform: uppercase;
} }
.form-group input[type='text'],
.form-group textarea { .form-group textarea {
width: 100%; width: 100%;
padding: 12px 14px; padding: 12px 14px;
@@ -827,31 +829,12 @@
min-height: 120px; min-height: 120px;
} }
.form-group input[type='text']:focus,
.form-group textarea:focus { .form-group textarea:focus {
outline: none; outline: none;
border-color: var(--accent-color, #419b38); border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08); box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
} }
.sidebar-input:focus {
outline: none;
border-bottom-color: var(--accent-color, #419b38);
}
.sidebar-input {
width: 100%;
padding: 10px 0;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
font-family: inherit;
font-size: 1rem;
color: var(--text-color);
box-sizing: border-box;
transition: border-bottom-color 0.3s ease;
}
.form-group textarea:focus { .form-group textarea:focus {
outline: none; outline: none;
border-color: var(--accent-color, #419b38); border-color: var(--accent-color, #419b38);
@@ -875,10 +858,6 @@
border-bottom: none; border-bottom: none;
} }
.series-weight-input {
margin-top: 10px;
}
.selected-tags-vertical { .selected-tags-vertical {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
+9 -45
View File
@@ -3,6 +3,7 @@
import type { ActionData, PageData } from './$types'; import type { ActionData, PageData } from './$types';
import { createSlugAutoHandler } from '$lib/utils/slugify'; import { createSlugAutoHandler } from '$lib/utils/slugify';
import { confirmState } from '$lib/stores/confirm.svelte'; import { confirmState } from '$lib/stores/confirm.svelte';
import TextInput from '$lib/components/admin/TextInput.svelte';
let { data, form }: { data: PageData; form: ActionData } = $props(); let { data, form }: { data: PageData; form: ActionData } = $props();
let name = $state(''); let name = $state('');
@@ -43,13 +44,14 @@
<form method="POST" action="?/create"> <form method="POST" action="?/create">
<div class="form-group"> <div class="form-group">
<label for="name">名称 *</label> <label for="name">名称 *</label>
<input <TextInput
id="name" id="name"
name="name" name="name"
type="text" type="text"
bind:value={name} bind:value={name}
oninput={handleNameInput} oninput={handleNameInput}
required required
variant="underline"
/> />
</div> </div>
@@ -68,13 +70,14 @@
{isGenerating ? '正在生成...' : '重新生成'} {isGenerating ? '正在生成...' : '重新生成'}
</button> </button>
</label> </label>
<input <TextInput
id="slug" id="slug"
name="slug" name="slug"
type="text" type="text"
bind:value={slug} bind:value={slug}
oninput={handleSlugInput} oninput={handleSlugInput}
required required
variant="underline"
/> />
</div> </div>
<button type="submit" class="btn btn-primary">创建</button> <button type="submit" class="btn btn-primary">创建</button>
@@ -103,13 +106,13 @@
<td>{item.id}</td> <td>{item.id}</td>
<td> <td>
{#if editingId === item.id} {#if editingId === item.id}
<input <TextInput
type="text" type="text"
name="name" name="name"
value={item.name} value={item.name}
form="edit-form-{item.id}" form="edit-form-{item.id}"
required required
class="edit-input" size="sm"
/> />
{:else} {:else}
<strong>{item.name}</strong> <strong>{item.name}</strong>
@@ -117,13 +120,13 @@
</td> </td>
<td> <td>
{#if editingId === item.id} {#if editingId === item.id}
<input <TextInput
type="text" type="text"
name="slug" name="slug"
value={item.slug} value={item.slug}
form="edit-form-{item.id}" form="edit-form-{item.id}"
required required
class="edit-input" size="sm"
/> />
{:else} {:else}
<span class="badge">{item.slug}</span> <span class="badge">{item.slug}</span>
@@ -251,24 +254,6 @@
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
.form-group input[type='text'] {
width: 100%;
padding: 10px 0;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
font-family: inherit;
font-size: 1.05rem;
color: var(--text-color);
box-sizing: border-box;
transition: border-bottom-color 0.3s ease;
}
.form-group input[type='text']:focus {
outline: none;
border-bottom-color: var(--accent-color, #419b38);
}
.btn { .btn {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
@@ -374,25 +359,4 @@
text-align: center; text-align: center;
color: var(--text-muted, rgba(0, 0, 0, 0.6)); color: var(--text-muted, rgba(0, 0, 0, 0.6));
} }
.edit-input {
width: 100%;
padding: 8px 10px;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 0;
background: rgba(0, 0, 0, 0.015);
font-family: inherit;
font-size: 0.95rem;
color: var(--text-color);
box-sizing: border-box;
transition:
border-color 0.3s ease,
box-shadow 0.3s ease;
}
.edit-input:focus {
outline: none;
border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
}
</style> </style>
+9 -24
View File
@@ -5,6 +5,7 @@
import Tabs from '$lib/components/admin/Tabs.svelte'; import Tabs from '$lib/components/admin/Tabs.svelte';
import ImagePicker from '$lib/components/admin/FeaturedImagePicker.svelte'; import ImagePicker from '$lib/components/admin/FeaturedImagePicker.svelte';
import DatePicker from '$lib/components/admin/DatePicker.svelte'; import DatePicker from '$lib/components/admin/DatePicker.svelte';
import TextInput from '$lib/components/admin/TextInput.svelte';
import { untrack } from 'svelte'; import { untrack } from 'svelte';
let { data, form }: { data: PageData; form: ActionData } = $props(); let { data, form }: { data: PageData; form: ActionData } = $props();
@@ -54,7 +55,7 @@
<div class="form-row"> <div class="form-row">
<div class="form-group"> <div class="form-group">
<label for="site_title">网站标题</label> <label for="site_title">网站标题</label>
<input <TextInput
type="text" type="text"
id="site_title" id="site_title"
name="site_title" name="site_title"
@@ -64,7 +65,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="site_description">站点描述</label> <label for="site_description">站点描述</label>
<input <TextInput
type="text" type="text"
id="site_description" id="site_description"
name="site_description" name="site_description"
@@ -78,7 +79,7 @@
<div class="form-row"> <div class="form-row">
<div class="form-group"> <div class="form-group">
<label for="r2_public_domain">R2 自定义域名</label> <label for="r2_public_domain">R2 自定义域名</label>
<input <TextInput
type="text" type="text"
id="r2_public_domain" id="r2_public_domain"
name="r2_public_domain" name="r2_public_domain"
@@ -200,7 +201,7 @@
<div class="form-row"> <div class="form-row">
<div class="form-group"> <div class="form-group">
<label for="alias_post">文章</label> <label for="alias_post">文章</label>
<input <TextInput
type="text" type="text"
id="alias_post" id="alias_post"
name="alias_post" name="alias_post"
@@ -210,7 +211,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="alias_page">页面</label> <label for="alias_page">页面</label>
<input <TextInput
type="text" type="text"
id="alias_page" id="alias_page"
name="alias_page" name="alias_page"
@@ -223,7 +224,7 @@
<div class="form-row"> <div class="form-row">
<div class="form-group"> <div class="form-group">
<label for="alias_category">分类</label> <label for="alias_category">分类</label>
<input <TextInput
type="text" type="text"
id="alias_category" id="alias_category"
name="alias_category" name="alias_category"
@@ -233,7 +234,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="alias_tag">标签</label> <label for="alias_tag">标签</label>
<input <TextInput
type="text" type="text"
id="alias_tag" id="alias_tag"
name="alias_tag" name="alias_tag"
@@ -243,7 +244,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="alias_series">系列</label> <label for="alias_series">系列</label>
<input <TextInput
type="text" type="text"
id="alias_series" id="alias_series"
name="alias_series" name="alias_series"
@@ -367,22 +368,6 @@
color: var(--text-color); color: var(--text-color);
} }
.form-group input {
padding: 10px 14px;
border: 1px solid rgba(0, 0, 0, 0.15);
background: rgba(0, 0, 0, 0.02);
font-size: 1rem;
color: var(--text-color);
border-radius: 0;
transition: all 0.2s;
}
.form-group input:focus {
outline: none;
border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 2px rgba(65, 155, 56, 0.1);
}
.form-actions { .form-actions {
margin-top: 10px; margin-top: 10px;
display: flex; display: flex;
+5 -42
View File
@@ -2,6 +2,7 @@
import { page } from '$app/stores'; import { page } from '$app/stores';
import type { PageData, ActionData } from './$types'; import type { PageData, ActionData } from './$types';
import { confirmState } from '$lib/stores/confirm.svelte'; import { confirmState } from '$lib/stores/confirm.svelte';
import TextInput from '$lib/components/admin/TextInput.svelte';
let { data, form }: { data: PageData; form: ActionData } = $props(); let { data, form }: { data: PageData; form: ActionData } = $props();
@@ -26,13 +27,14 @@
<form method="POST" action="?/create"> <form method="POST" action="?/create">
<div class="form-group"> <div class="form-group">
<label for="name">名称 *</label> <label for="name">名称 *</label>
<input <TextInput
type="text" type="text"
id="name" id="name"
name="name" name="name"
bind:value={newTagName} bind:value={newTagName}
placeholder="例如: SvelteKit" placeholder="例如: SvelteKit"
required required
variant="underline"
/> />
</div> </div>
<button type="submit" class="btn btn-primary">创建</button> <button type="submit" class="btn btn-primary">创建</button>
@@ -61,13 +63,13 @@
<td>{tag.id}</td> <td>{tag.id}</td>
<td> <td>
{#if editingId === tag.id} {#if editingId === tag.id}
<input <TextInput
type="text" type="text"
name="name" name="name"
value={tag.name} value={tag.name}
form="edit-form-{tag.id}" form="edit-form-{tag.id}"
required required
class="edit-input" size="sm"
/> />
{:else} {:else}
<strong>{tag.name}</strong> <strong>{tag.name}</strong>
@@ -195,24 +197,6 @@
letter-spacing: 0.5px; letter-spacing: 0.5px;
} }
.form-group input[type='text'] {
width: 100%;
padding: 10px 0;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.1);
background: transparent;
font-family: inherit;
font-size: 1.05rem;
color: var(--text-color);
box-sizing: border-box;
transition: border-bottom-color 0.3s ease;
}
.form-group input[type='text']:focus {
outline: none;
border-bottom-color: var(--accent-color, #419b38);
}
.btn { .btn {
display: inline-block; display: inline-block;
width: 100%; width: 100%;
@@ -318,25 +302,4 @@
text-align: center; text-align: center;
color: var(--text-muted, rgba(0, 0, 0, 0.6)); color: var(--text-muted, rgba(0, 0, 0, 0.6));
} }
.edit-input {
width: 100%;
padding: 8px 10px;
border: 1px solid rgba(0, 0, 0, 0.12);
border-radius: 0;
background: rgba(0, 0, 0, 0.015);
font-family: inherit;
font-size: 0.95rem;
color: var(--text-color);
box-sizing: border-box;
transition:
border-color 0.3s ease,
box-shadow 0.3s ease;
}
.edit-input:focus {
outline: none;
border-color: var(--accent-color, #419b38);
box-shadow: 0 0 0 3px rgba(65, 155, 56, 0.08);
}
</style> </style>