mirror of
https://github.com/yeban8090/book-smith.git
synced 2026-07-22 05:46:23 +00:00
优化完成
This commit is contained in:
parent
3eaa0a1017
commit
9b5af8a672
5 changed files with 195 additions and 271 deletions
|
|
@ -143,37 +143,31 @@ export class TypographyView {
|
|||
// 按照要求的顺序创建顶部选择器:书籍、模板、主题、字体、字号大小
|
||||
private createTopSelectors(container: HTMLElement) {
|
||||
// 创建第一行选择器容器
|
||||
const selectorsRow1 = container.createDiv({ cls: 'typography-selectors-row' });
|
||||
|
||||
const selectorsRow = container.createDiv({ cls: 'typography-selectors-row' });
|
||||
// 1. 创建书籍选择器
|
||||
this.createBookSelector(selectorsRow1);
|
||||
|
||||
this.createBookSelector(selectorsRow);
|
||||
// 2. 创建模板选择器
|
||||
this.createTemplateSelector(selectorsRow1);
|
||||
this.createTemplateSelector(selectorsRow);
|
||||
|
||||
// 3. 创建主题选择器
|
||||
this.createThemeSelector(selectorsRow1);
|
||||
|
||||
// 创建第二行选择器容器
|
||||
const selectorsRow2 = container.createDiv({ cls: 'typography-selectors-row' });
|
||||
|
||||
this.createThemeSelector(selectorsRow);
|
||||
// 4. 创建字体选择器
|
||||
this.createFontSelector(selectorsRow2);
|
||||
this.createFontSelector(selectorsRow);
|
||||
|
||||
// 5. 创建字号大小控制
|
||||
this.createFontSizeControls(selectorsRow2);
|
||||
|
||||
this.createFontSizeControls(selectorsRow);
|
||||
|
||||
// 6. 创建开本大小选择器
|
||||
this.createBookSizeSelector(selectorsRow2);
|
||||
this.createBookSizeSelector(selectorsRow);
|
||||
}
|
||||
|
||||
// 自定义选择器通用方法
|
||||
private createCustomSelect(parent: HTMLElement, className: string, options: { value: string, text: string }[]): HTMLElement {
|
||||
const container = parent.createDiv({ cls: `red-select-container ${className}` });
|
||||
const container = parent.createDiv({ cls: `book-smith-select-container ${className}` });
|
||||
|
||||
const select = container.createDiv({ cls: 'red-select' });
|
||||
const textSpan = select.createSpan({ cls: 'red-text' });
|
||||
const arrowSpan = select.createSpan({ cls: 'red-select-arrow' });
|
||||
const select = container.createDiv({ cls: 'book-smith-select' });
|
||||
const textSpan = select.createSpan({ cls: 'book-smith-text' });
|
||||
const arrowSpan = select.createSpan({ cls: 'book-smith-select-arrow' });
|
||||
setIcon(arrowSpan, 'chevron-down');
|
||||
|
||||
// 默认选择第一个选项
|
||||
|
|
@ -183,17 +177,17 @@ export class TypographyView {
|
|||
}
|
||||
|
||||
// 创建下拉菜单
|
||||
const dropdown = container.createDiv({ cls: 'red-select-dropdown' });
|
||||
const dropdown = container.createDiv({ cls: 'book-smith-select-dropdown' });
|
||||
|
||||
// 添加选项
|
||||
for (const option of options) {
|
||||
const item = dropdown.createDiv({ cls: 'red-select-item' });
|
||||
const item = dropdown.createDiv({ cls: 'book-smith-select-item' });
|
||||
item.textContent = option.text;
|
||||
item.dataset.value = option.value;
|
||||
|
||||
// 默认选中第一个
|
||||
if (options.indexOf(option) === 0) {
|
||||
item.addClass('red-selected');
|
||||
item.addClass('book-smith-selected');
|
||||
}
|
||||
|
||||
// 点击选项
|
||||
|
|
@ -203,13 +197,13 @@ export class TypographyView {
|
|||
select.dataset.value = option.value;
|
||||
|
||||
// 更新选中状态
|
||||
dropdown.querySelectorAll('.red-select-item').forEach(el => {
|
||||
el.removeClass('red-selected');
|
||||
dropdown.querySelectorAll('.book-select-item').forEach(el => {
|
||||
el.removeClass('book-smith-selected');
|
||||
});
|
||||
item.addClass('red-selected');
|
||||
item.addClass('book-smith-selected');
|
||||
|
||||
// 关闭下拉菜单
|
||||
dropdown.removeClass('red-show');
|
||||
dropdown.removeClass('book-smith-show');
|
||||
arrowSpan.style.transform = '';
|
||||
|
||||
// 触发自定义事件
|
||||
|
|
@ -222,13 +216,13 @@ export class TypographyView {
|
|||
// 点击选择器显示/隐藏下拉菜单
|
||||
select.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
dropdown.toggleClass('red-show', !dropdown.hasClass('red-show'));
|
||||
arrowSpan.style.transform = dropdown.hasClass('red-show') ? 'rotate(180deg)' : '';
|
||||
dropdown.toggleClass('book-smith-show', !dropdown.hasClass('book-smith-show'));
|
||||
arrowSpan.style.transform = dropdown.hasClass('book-smith-show') ? 'rotate(180deg)' : '';
|
||||
});
|
||||
|
||||
// 点击其他地方关闭下拉菜单
|
||||
document.addEventListener('click', () => {
|
||||
dropdown.removeClass('red-show');
|
||||
dropdown.removeClass('book-smith-show');
|
||||
arrowSpan.style.transform = '';
|
||||
});
|
||||
|
||||
|
|
@ -237,9 +231,9 @@ export class TypographyView {
|
|||
|
||||
// 更新自定义选择器的选项
|
||||
private updateCustomSelectOptions(selectElement: HTMLElement, options: { value: string, text: string }[]) {
|
||||
const dropdown = selectElement.querySelector('.red-select-dropdown');
|
||||
const select = selectElement.querySelector('.red-select');
|
||||
const textSpan = selectElement.querySelector('.red-text');
|
||||
const dropdown = selectElement.querySelector('.book-smith-select-dropdown');
|
||||
const select = selectElement.querySelector('.book-smith-select');
|
||||
const textSpan = selectElement.querySelector('.book-smith-text');
|
||||
|
||||
if (!dropdown || !select || !textSpan) return;
|
||||
|
||||
|
|
@ -248,13 +242,13 @@ export class TypographyView {
|
|||
|
||||
// 添加新选项
|
||||
for (const option of options) {
|
||||
const item = dropdown.createDiv({ cls: 'red-select-item' });
|
||||
const item = dropdown.createDiv({ cls: 'book-smith-select-item' });
|
||||
item.textContent = option.text;
|
||||
item.dataset.value = option.value;
|
||||
|
||||
// 默认选中第一个
|
||||
if (options.indexOf(option) === 0) {
|
||||
item.addClass('red-selected');
|
||||
item.addClass('book-smith-selected');
|
||||
textSpan.textContent = option.text;
|
||||
(select as HTMLElement).setAttribute('data-value', option.value);
|
||||
}
|
||||
|
|
@ -266,13 +260,13 @@ export class TypographyView {
|
|||
(select as HTMLElement).setAttribute('data-value', option.value);
|
||||
|
||||
// 更新选中状态
|
||||
dropdown.querySelectorAll('.red-select-item').forEach(el => {
|
||||
el.removeClass('red-selected');
|
||||
dropdown.querySelectorAll('.book-smith-select-item').forEach(el => {
|
||||
el.removeClass('book-smith-selected');
|
||||
});
|
||||
item.addClass('red-selected');
|
||||
item.addClass('book-smith-selected');
|
||||
|
||||
// 关闭下拉菜单
|
||||
dropdown.removeClass('red-show');
|
||||
dropdown.removeClass('book-smith-show');
|
||||
|
||||
// 触发自定义事件
|
||||
select.dispatchEvent(new CustomEvent('change', {
|
||||
|
|
@ -301,7 +295,7 @@ export class TypographyView {
|
|||
// 创建自定义选择器
|
||||
this.customBookSelect = this.createCustomSelect(
|
||||
parent,
|
||||
'red-book-select',
|
||||
'book-smith-book-select',
|
||||
bookOptions
|
||||
);
|
||||
this.customBookSelect.id = 'book-select';
|
||||
|
|
@ -321,7 +315,7 @@ export class TypographyView {
|
|||
this.updateCustomSelectOptions(this.customBookSelect, bookOptions);
|
||||
|
||||
// 添加事件监听
|
||||
this.customBookSelect.querySelector('.red-select')?.addEventListener('change', async (e: any) => {
|
||||
this.customBookSelect.querySelector('.book-smith-select')?.addEventListener('change', async (e: any) => {
|
||||
const value = e.detail.value;
|
||||
this.selectedBook = this.books.find(book => book.basic.uuid === value) || null;
|
||||
this.updatePreview();
|
||||
|
|
@ -329,7 +323,7 @@ export class TypographyView {
|
|||
|
||||
// 如果有书籍,选择第一本
|
||||
if (bookOptions.length > 0) {
|
||||
const select = this.customBookSelect.querySelector('.red-select');
|
||||
const select = this.customBookSelect.querySelector('.book-smith-select');
|
||||
if (select) {
|
||||
(select as HTMLElement).setAttribute('data-value', bookOptions[0].value);
|
||||
this.selectedBook = this.books[0];
|
||||
|
|
@ -342,7 +336,7 @@ export class TypographyView {
|
|||
private createTemplateSelector(parent: HTMLElement) {
|
||||
this.customTemplateSelect = this.createCustomSelect(
|
||||
parent,
|
||||
'red-template-select',
|
||||
'book-smith-template-select',
|
||||
[{ value: '', text: i18n.t('LOADING') || '加载中...' }]
|
||||
);
|
||||
this.customTemplateSelect.id = 'template-select';
|
||||
|
|
@ -359,7 +353,7 @@ export class TypographyView {
|
|||
this.updateCustomSelectOptions(this.customTemplateSelect, templateOptions);
|
||||
|
||||
// 添加事件监听
|
||||
this.customTemplateSelect.querySelector('.red-select')?.addEventListener('change', async (e: any) => {
|
||||
this.customTemplateSelect.querySelector('.book-smith-select')?.addEventListener('change', async (e: any) => {
|
||||
const value = e.detail.value;
|
||||
this.currentTemplate = this.imgTemplateManager.getTemplate(value) || null;
|
||||
this.updatePreview();
|
||||
|
|
@ -367,7 +361,7 @@ export class TypographyView {
|
|||
|
||||
// 默认选择第一个模板
|
||||
if (templateOptions.length > 0) {
|
||||
const select = this.customTemplateSelect.querySelector('.red-select');
|
||||
const select = this.customTemplateSelect.querySelector('.book-smith-select');
|
||||
if (select) {
|
||||
(select as HTMLElement).setAttribute('data-value', templateOptions[0].value);
|
||||
this.currentTemplate = this.imgTemplateManager.getTemplate(templateOptions[0].value) || null;
|
||||
|
|
@ -379,7 +373,7 @@ export class TypographyView {
|
|||
private createThemeSelector(parent: HTMLElement) {
|
||||
this.customThemeSelect = this.createCustomSelect(
|
||||
parent,
|
||||
'red-theme-select',
|
||||
'book-smith-theme-select',
|
||||
[{ value: '', text: i18n.t('LOADING') || '加载中...' }]
|
||||
);
|
||||
this.customThemeSelect.id = 'theme-select';
|
||||
|
|
@ -396,7 +390,7 @@ export class TypographyView {
|
|||
this.updateCustomSelectOptions(this.customThemeSelect, themes);
|
||||
|
||||
// 添加事件监听
|
||||
this.customThemeSelect.querySelector('.red-select')?.addEventListener('change', async (e: any) => {
|
||||
this.customThemeSelect.querySelector('.book-smith-select')?.addEventListener('change', async (e: any) => {
|
||||
const value = e.detail.value;
|
||||
this.themeManager.setCurrentTheme(value);
|
||||
if (this.previewElement) {
|
||||
|
|
@ -406,7 +400,7 @@ export class TypographyView {
|
|||
|
||||
// 默认选择第一个主题
|
||||
if (themes.length > 0) {
|
||||
const select = this.customThemeSelect.querySelector('.red-select');
|
||||
const select = this.customThemeSelect.querySelector('.book-smith-select');
|
||||
if (select) {
|
||||
(select as HTMLElement).setAttribute('data-value', themes[0].value);
|
||||
this.themeManager.setCurrentTheme(themes[0].value);
|
||||
|
|
@ -429,7 +423,7 @@ export class TypographyView {
|
|||
|
||||
this.customFontSelect = this.createCustomSelect(
|
||||
parent,
|
||||
'red-font-select',
|
||||
'book-smith-font-select',
|
||||
fontOptions
|
||||
);
|
||||
this.customFontSelect.id = 'font-select';
|
||||
|
|
@ -440,23 +434,23 @@ export class TypographyView {
|
|||
if (!this.customFontSelect) return;
|
||||
|
||||
// 添加事件监听
|
||||
this.customFontSelect.querySelector('.red-select')?.addEventListener('change', () => {
|
||||
this.customFontSelect.querySelector('.book-smith-select')?.addEventListener('change', () => {
|
||||
this.updatePreview();
|
||||
});
|
||||
}
|
||||
|
||||
// 5. 字号大小控制
|
||||
private createFontSizeControls(parent: HTMLElement) {
|
||||
const fontSizeGroup = parent.createEl('div', { cls: 'red-font-size-group' });
|
||||
const fontSizeGroup = parent.createEl('div', { cls: 'book-smith-font-size-group' });
|
||||
|
||||
// 添加减小按钮
|
||||
const decreaseButton = fontSizeGroup.createEl('button', {
|
||||
cls: 'red-font-size-button red-decrease-button',
|
||||
cls: 'book-smith-font-size-button book-smith-decrease-button',
|
||||
text: '-'
|
||||
});
|
||||
|
||||
this.fontSizeInput = fontSizeGroup.createEl('input', {
|
||||
cls: 'red-font-size-input',
|
||||
cls: 'book-smith-font-size-input',
|
||||
type: 'text',
|
||||
value: '16',
|
||||
attr: {
|
||||
|
|
@ -468,13 +462,13 @@ export class TypographyView {
|
|||
|
||||
// 添加增大按钮
|
||||
const increaseButton = fontSizeGroup.createEl('button', {
|
||||
cls: 'red-font-size-button red-increase-button',
|
||||
cls: 'book-smith-font-size-button book-smith-increase-button',
|
||||
text: '+'
|
||||
});
|
||||
|
||||
// 添加单位标签
|
||||
fontSizeGroup.createEl('span', {
|
||||
cls: 'red-font-size-unit'
|
||||
cls: 'book-smith-font-size-unit'
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -500,8 +494,8 @@ export class TypographyView {
|
|||
};
|
||||
|
||||
// 获取按钮元素
|
||||
const decreaseButton = this.fontSizeInput.parentElement?.querySelector('.red-decrease-button');
|
||||
const increaseButton = this.fontSizeInput.parentElement?.querySelector('.red-increase-button');
|
||||
const decreaseButton = this.fontSizeInput.parentElement?.querySelector('.book-smith-decrease-button');
|
||||
const increaseButton = this.fontSizeInput.parentElement?.querySelector('.book-smith-increase-button');
|
||||
|
||||
// 添加减小字号事件
|
||||
decreaseButton?.addEventListener('click', () => {
|
||||
|
|
@ -557,7 +551,7 @@ export class TypographyView {
|
|||
|
||||
this.customBookSizeSelect = this.createCustomSelect(
|
||||
parent,
|
||||
'red-book-size-select',
|
||||
'book-smith-book-size-select',
|
||||
bookSizeOptions
|
||||
);
|
||||
this.customBookSizeSelect.id = 'book-size-select';
|
||||
|
|
@ -568,7 +562,7 @@ export class TypographyView {
|
|||
if (!this.customBookSizeSelect) return;
|
||||
|
||||
// 添加事件监听
|
||||
this.customBookSizeSelect.querySelector('.red-select')?.addEventListener('change', () => {
|
||||
this.customBookSizeSelect.querySelector('.book-smith-select')?.addEventListener('change', () => {
|
||||
this.updatePreview();
|
||||
});
|
||||
}
|
||||
|
|
@ -580,15 +574,15 @@ export class TypographyView {
|
|||
const showCover = coverToggle ? coverToggle.checked : true;
|
||||
|
||||
return {
|
||||
fontFamily: (this.customFontSelect?.querySelector('.red-select') as HTMLElement)?.getAttribute('data-value') || 'default',
|
||||
fontFamily: (this.customFontSelect?.querySelector('.book-smith-select') as HTMLElement)?.getAttribute('data-value') || 'default',
|
||||
fontSize: this.fontSizeInput?.value || '16',
|
||||
lineHeight: 'normal', // 保留默认值
|
||||
margin: '0', // 保留默认值
|
||||
templateId: (this.customTemplateSelect?.querySelector('.red-select') as HTMLElement)?.getAttribute('data-value') || 'notes',
|
||||
themeId: (this.customThemeSelect?.querySelector('.red-select') as HTMLElement)?.getAttribute('data-value') || 'default',
|
||||
templateId: (this.customTemplateSelect?.querySelector('.book-smith-select') as HTMLElement)?.getAttribute('data-value') || 'notes',
|
||||
themeId: (this.customThemeSelect?.querySelector('.book-smith-select') as HTMLElement)?.getAttribute('data-value') || 'default',
|
||||
coverSettings: this.coverSettings || undefined,
|
||||
showCover: showCover,
|
||||
bookSize: (this.customBookSizeSelect?.querySelector('.red-select') as HTMLElement)?.getAttribute('data-value') || 'a4'
|
||||
bookSize: (this.customBookSizeSelect?.querySelector('.book-smith-select') as HTMLElement)?.getAttribute('data-value') || 'a4'
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -766,16 +760,13 @@ export class TypographyView {
|
|||
const buttonsContainer = container.createDiv({ cls: 'typography-buttons-container' });
|
||||
|
||||
// 第一行按钮组 - 封面相关
|
||||
const coverButtonsGroup = buttonsContainer.createDiv({ cls: 'typography-buttons-group cover-buttons-group' });
|
||||
const buttonsGroup = buttonsContainer.createDiv({ cls: 'typography-buttons-group cover-buttons-group' });
|
||||
|
||||
// 添加封面设计开关
|
||||
this.createCoverToggle(coverButtonsGroup);
|
||||
|
||||
// 第二行按钮组 - 操作按钮
|
||||
const actionButtonsGroup = buttonsContainer.createDiv({ cls: 'typography-buttons-group action-buttons-group' });
|
||||
this.createCoverToggle(buttonsGroup);
|
||||
|
||||
// 应用按钮
|
||||
const applyBtn = actionButtonsGroup.createEl('button', {
|
||||
const applyBtn = buttonsGroup.createEl('button', {
|
||||
text: i18n.t('APPLY') || '应用',
|
||||
cls: 'typography-btn apply-btn'
|
||||
});
|
||||
|
|
@ -785,7 +776,7 @@ export class TypographyView {
|
|||
});
|
||||
|
||||
// 导出按钮
|
||||
const exportBtn = actionButtonsGroup.createEl('button', {
|
||||
const exportBtn = buttonsGroup.createEl('button', {
|
||||
text: i18n.t('EXPORT') || '导出',
|
||||
cls: 'typography-btn export-btn'
|
||||
});
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ const toolbarModalTranslation: ToolbarModalTranslation = {
|
|||
|
||||
// TypographyModal
|
||||
PREVIEW: '预览',
|
||||
NO_BOOKS_AVAILABLE: '没有可用的书籍',
|
||||
NO_BOOKS_AVAILABLE: '无书籍',
|
||||
LOADING: '加载中...',
|
||||
DEFAULT_FONT: '默认字体',
|
||||
SERIF_FONT: '衬线字体',
|
||||
|
|
|
|||
|
|
@ -100,7 +100,6 @@
|
|||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 0; /* 移除底部边距 */
|
||||
justify-content: center; /* 居中显示 */
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,19 +123,6 @@
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 封面和内容容器 */
|
||||
.typography-preview-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.typography-cover-container,
|
||||
.typography-content-container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 页码样式 */
|
||||
.page-number {
|
||||
position: absolute;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
.typography-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
padding: 0 16px;
|
||||
background-color: var(--background-secondary);
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
|
|
@ -25,13 +25,13 @@
|
|||
flex: 1;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.typography-exit-btn {
|
||||
cursor: pointer;
|
||||
color: var(--text-muted);
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.typography-exit-btn:hover {
|
||||
|
|
@ -47,22 +47,21 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 顶部选择器面板样式 - 防止换行 */
|
||||
/* 顶部面板样式 */
|
||||
.typography-top-panel {
|
||||
padding: 16px;
|
||||
max-width: 686px;
|
||||
padding: 10px;
|
||||
max-width: 680px;
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
background-color: var(--background-secondary-alt);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 选择器行容器样式 */
|
||||
.typography-selectors-row {
|
||||
display: flex;
|
||||
flex-wrap: nowrap; /* 防止换行 */
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: center; /* 居中排列 */
|
||||
min-width: min-content; /* 确保内容不会被压缩 */
|
||||
|
|
@ -70,25 +69,12 @@
|
|||
margin: 0 auto; /* 居中显示 */
|
||||
}
|
||||
|
||||
/* 移除原有的选择器容器样式 */
|
||||
/* .typography-selectors {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
min-width: min-content;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
} */
|
||||
|
||||
/* 自定义选择器容器样式 */
|
||||
.red-select-container {
|
||||
.book-smith-select-container {
|
||||
position: relative;
|
||||
flex: 0 0 auto; /* 防止压缩 */
|
||||
min-width: 120px; /* 最小宽度 */
|
||||
max-width: 200px; /* 最大宽度 */
|
||||
|
||||
}
|
||||
|
||||
/* 表单字段样式 */
|
||||
|
|
@ -105,64 +91,14 @@
|
|||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 选择器样式 */
|
||||
.typography-selectors select {
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
background-color: var(--background-primary);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
color: var(--text-normal);
|
||||
font-size: 14px;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 8px center;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
.typography-selectors select:focus {
|
||||
border-color: var(--interactive-accent);
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(var(--interactive-accent-rgb), 0.2);
|
||||
}
|
||||
|
||||
.typography-selectors select:hover {
|
||||
border-color: var(--interactive-hover);
|
||||
}
|
||||
|
||||
/* 选择器容器样式 */
|
||||
.typography-selectors {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 表单字段样式 - 移除垂直布局 */
|
||||
.form-field {
|
||||
display: inline-block;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
font-weight: 500;
|
||||
color: var(--text-normal);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* 预览面板样式 - 添加滚动条支持 */
|
||||
/* 预览面板样式 */
|
||||
.typography-preview-panel {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center; /* 确保内容居中 */
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 预览容器样式 - 添加居中和缩放支持 */
|
||||
|
|
@ -214,7 +150,7 @@
|
|||
|
||||
/* 底部按钮面板样式 */
|
||||
.typography-bottom-panel {
|
||||
padding: 16px;
|
||||
padding: 10px 30px 0 36px;
|
||||
border-top: 1px solid var(--background-modifier-border);
|
||||
background-color: var(--background-secondary-alt);
|
||||
}
|
||||
|
|
@ -286,7 +222,6 @@
|
|||
50% { background-color: var(--interactive-accent-hover); }
|
||||
100% { background-color: var(--background-primary); }
|
||||
}
|
||||
|
||||
/* 字体样式 */
|
||||
.font-default {
|
||||
font-family: var(--default-font);
|
||||
|
|
@ -452,7 +387,9 @@
|
|||
transition: background-color 0.5s ease;
|
||||
}
|
||||
|
||||
.red-select {
|
||||
/* 自定义选择器样式 */
|
||||
.book-smith-select {
|
||||
max-width: 112px;
|
||||
height: 36px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
|
|
@ -469,8 +406,15 @@
|
|||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
.book-smith-book-size-select .book-smith-select{
|
||||
max-width: 76px;
|
||||
}
|
||||
.book-smith-select:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
box-shadow: 0 2px 6px var(--background-modifier-box-shadow);
|
||||
}
|
||||
|
||||
.red-text {
|
||||
.book-smith-text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
|
@ -478,29 +422,13 @@
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
.red-select:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
box-shadow: 0 2px 6px var(--background-modifier-box-shadow);
|
||||
}
|
||||
|
||||
.red-select.disabled {
|
||||
opacity: 0.5;
|
||||
background: var(--background-secondary) !important;
|
||||
color: var(--text-muted) !important;
|
||||
border-color: var(--background-modifier-border) !important;
|
||||
cursor: not-allowed;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.red-select-arrow {
|
||||
color: var(--text-normal);
|
||||
font-size: 12px;
|
||||
.book-smith-select-arrow {
|
||||
margin-left: 8px;
|
||||
transition: transform 0.2s ease;
|
||||
margin-left: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.red-select-dropdown {
|
||||
/* 选择器下拉菜单样式 */
|
||||
.book-smith-select-dropdown {
|
||||
position: absolute;
|
||||
top: calc(100% + 4px);
|
||||
left: 0;
|
||||
|
|
@ -514,28 +442,28 @@
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.red-select-dropdown.red-show {
|
||||
.book-smith-select-dropdown.book-smith-show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.red-select-item {
|
||||
.book-smith-select-item {
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
color: var(--text-normal);
|
||||
}
|
||||
|
||||
.red-select-item:hover {
|
||||
.book-smith-select-item:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
.red-select-item.red-selected {
|
||||
.book-smith-select-item.book-smith-selected {
|
||||
background: var(--background-modifier-hover);
|
||||
color: var(--text-accent);
|
||||
}
|
||||
|
||||
/* ===== 字号调整组件 ===== */
|
||||
.red-font-size-group {
|
||||
/* 字体大小控制组样式 */
|
||||
.book-smith-font-size-group {
|
||||
min-width: 36px;
|
||||
max-width: 120px;
|
||||
height: 36px;
|
||||
|
|
@ -546,17 +474,17 @@
|
|||
background: var(--background-primary);
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 8px;
|
||||
padding: 0;
|
||||
margin: 0 10px 0 1px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 3px var(--background-modifier-box-shadow);
|
||||
}
|
||||
|
||||
.red-font-size-input {
|
||||
.book-smith-font-size-input {
|
||||
width: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.red-font-size-btn {
|
||||
.book-smith-font-size-btn {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
|
|
@ -570,131 +498,150 @@
|
|||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.red-font-size-btn:hover {
|
||||
.book-smith-font-size-btn:hover {
|
||||
background: var(--background-modifier-hover);
|
||||
}
|
||||
|
||||
|
||||
/* 开本大小样式 */
|
||||
.book-size-a4 {
|
||||
aspect-ratio: 1 / 1.414; /* A4 比例 */
|
||||
max-width: 595px; /* A4 宽度 */
|
||||
width: 210mm;
|
||||
min-height: 297mm;
|
||||
max-height: 297mm;
|
||||
}
|
||||
|
||||
.book-size-a5 {
|
||||
aspect-ratio: 1 / 1.414; /* A5 比例 */
|
||||
max-width: 420px; /* A5 宽度 */
|
||||
width: 148mm;
|
||||
min-height: 210mm;
|
||||
max-height: 210mm;
|
||||
}
|
||||
|
||||
.book-size-b5 {
|
||||
aspect-ratio: 1 / 1.414; /* B5 比例 */
|
||||
max-width: 498px; /* B5 宽度 */
|
||||
width: 176mm;
|
||||
min-height: 250mm;
|
||||
max-height: 250mm;
|
||||
}
|
||||
|
||||
.book-size-16k {
|
||||
aspect-ratio: 1 / 1.5; /* 16K 比例 */
|
||||
max-width: 460px; /* 16K 宽度 */
|
||||
width: 184mm;
|
||||
min-height: 260mm;
|
||||
max-height: 260mm;
|
||||
}
|
||||
|
||||
.book-size-custom {
|
||||
width: 180mm;
|
||||
min-height: 240mm;
|
||||
max-height: 240mm;
|
||||
}
|
||||
|
||||
/* 简洁模板样式 */
|
||||
.simple-template {
|
||||
background-color: white;
|
||||
padding: 20px;
|
||||
font-family: var(--font-text, sans-serif);
|
||||
max-width: 800px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
|
||||
/* 分页容器 */
|
||||
.typography-paged-content {
|
||||
column-count: 2;
|
||||
column-gap: 40px;
|
||||
column-fill: auto;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 页面样式 */
|
||||
.typography-page {
|
||||
break-inside: avoid;
|
||||
page-break-inside: avoid;
|
||||
.simple-template .header {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: white;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
/* 章节标题强制分页 */
|
||||
h1, h2 {
|
||||
break-before: page;
|
||||
page-break-before: always;
|
||||
}
|
||||
|
||||
/* 目录样式 */
|
||||
.typography-toc {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.typography-toc-item {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.typography-toc-level-1 {
|
||||
.simple-template .title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
margin-left: 0;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.typography-toc-level-2 {
|
||||
margin-left: 20px;
|
||||
.simple-template .meta {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.typography-toc-level-3 {
|
||||
margin-left: 40px;
|
||||
.simple-template .abstract {
|
||||
font-style: italic;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px;
|
||||
background-color: #f5f5f5;
|
||||
border-left: 3px solid #ddd;
|
||||
}
|
||||
|
||||
/* 添加到 styles/views/typography.css 或直接在 TypographyView 中添加样式 */
|
||||
.typography-content-pages {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
.simple-template .content {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.book-page {
|
||||
border: 1px solid #ddd;
|
||||
padding: 20px;
|
||||
.simple-template .footer {
|
||||
margin-top: 30px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #eee;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
/* 文章模板样式 */
|
||||
.article-template {
|
||||
background-color: white;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
min-height: 200px;
|
||||
max-height: 800px;
|
||||
overflow: hidden;
|
||||
page-break-after: always;
|
||||
position: relative;
|
||||
padding: 30px;
|
||||
font-family: var(--font-text, serif);
|
||||
max-width: 800px;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
/* 目录样式 */
|
||||
.typography-toc {
|
||||
.article-template .header {
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.article-template .title {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.article-template .meta {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.article-template .abstract {
|
||||
font-style: italic;
|
||||
margin: 0 auto 30px;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
background-color: #f9f9f9;
|
||||
border-left: 4px solid #ddd;
|
||||
max-width: 80%;
|
||||
}
|
||||
|
||||
.toc-list {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
.article-template .content {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.toc-list ul {
|
||||
padding-left: 20px;
|
||||
list-style-type: none;
|
||||
.article-template .footer {
|
||||
margin-top: 40px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #eee;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.toc-list li {
|
||||
margin: 5px 0;
|
||||
.article-template blockquote {
|
||||
margin: 20px 0;
|
||||
padding: 10px 20px;
|
||||
background-color: #f9f9f9;
|
||||
border-left: 4px solid #ddd;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.toc-list a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
.article-template .copyright {
|
||||
margin-top: 20px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.toc-list a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
/* 选择器高亮效果 */
|
||||
.selected-option {
|
||||
background-color: var(--interactive-accent);
|
||||
color: var(--text-on-accent);
|
||||
}
|
||||
Loading…
Reference in a new issue