This commit is contained in:
1 parent
40ffee0c91
commit
45fe86cbbb
9 files changed
+136
-264
No files matched your search
@@ -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>
|
||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>
|
||||||
Reference in new issue
Block a user