Skip to content

Commit c972417

Browse files
EstrellaXDclaude
andcommitted
fix(ui): improve edit rule dialog layout and button consistency
- Increase dialog width from 380px to 460px to fit all content - Unify button heights across ab-button and ab-button-multi components - small: 32px, normal: 36px, big: 44px - Restructure ab-rule form layout with consistent gap spacing - Fix Episode Offset row to keep input and button on same line (mobile) - Add proper z-index layering for ab-bottom-sheet (backdrop: 100, container: 101, panel: 102) - Add scoped styles for ab-setting dynamic-tags wrapper - Add action button separator line in edit dialog Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent ecd7914 commit c972417

7 files changed

Lines changed: 96 additions & 52 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
- 规则编辑弹窗新增归档/取消归档按钮
3636
- 规则编辑器新增剧集偏移字段和「自动检测」按钮
3737
- 新增 i18n 翻译(中文/英文)
38+
- 优化规则编辑弹窗布局:统一表单字段对齐、统一按钮高度、修复移动端底部弹窗 z-index 层级问题
3839

3940
---
4041

webui/src/components/ab-edit-rule.vue

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ const boxSize = computed(() => {
7979
if (rule.value.deleted) {
8080
return 'w-300';
8181
} else {
82-
return 'w-380';
82+
return 'w-460';
8383
}
8484
});
8585
</script>
@@ -105,10 +105,10 @@ const boxSize = computed(() => {
105105
</div>
106106
</div>
107107

108-
<div v-else space-y-12>
108+
<div v-else class="edit-rule-content">
109109
<ab-rule v-model:rule="rule"></ab-rule>
110110

111-
<div fx-cer justify-end gap-x-10>
111+
<div class="edit-rule-actions">
112112
<ab-button
113113
v-if="rule.archived"
114114
size="small"
@@ -153,3 +153,22 @@ const boxSize = computed(() => {
153153
</ab-popup>
154154
</ab-popup>
155155
</template>
156+
157+
<style lang="scss" scoped>
158+
.edit-rule-content {
159+
display: flex;
160+
flex-direction: column;
161+
gap: 20px;
162+
}
163+
164+
.edit-rule-actions {
165+
display: flex;
166+
align-items: center;
167+
justify-content: flex-end;
168+
gap: 10px;
169+
padding-top: 4px;
170+
border-top: 1px solid var(--color-border);
171+
padding-top: 16px;
172+
flex-wrap: wrap;
173+
}
174+
</style>

webui/src/components/ab-rule.vue

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,17 @@ const items: SettingItem<BangumiRule>[] = [
5252
prop: {
5353
type: 'number',
5454
},
55-
bottomLine: true,
5655
},
5756
{
5857
configKey: 'filter',
5958
label: () => t('homepage.rule.exclude'),
6059
type: 'dynamic-tags',
61-
bottomLine: true,
6260
},
6361
];
6462
</script>
6563

6664
<template>
67-
<div space-y-12>
65+
<div class="rule-form">
6866
<ab-setting
6967
v-for="i in items"
7068
:key="i.configKey"
@@ -73,12 +71,12 @@ const items: SettingItem<BangumiRule>[] = [
7371
></ab-setting>
7472

7573
<!-- Offset field with auto-detect button -->
76-
<div class="offset-row">
77-
<div class="offset-label">{{ $t('homepage.rule.offset') }}</div>
74+
<ab-label :label="() => $t('homepage.rule.offset')">
7875
<div class="offset-controls">
7976
<input
8077
v-model.number="rule.offset"
8178
type="number"
79+
ab-input
8280
class="offset-input"
8381
/>
8482
<ab-button
@@ -89,47 +87,50 @@ const items: SettingItem<BangumiRule>[] = [
8987
{{ $t('homepage.rule.auto_detect') }}
9088
</ab-button>
9189
</div>
92-
<div v-if="offsetReason" class="offset-reason">{{ offsetReason }}</div>
93-
</div>
90+
</ab-label>
91+
92+
<div v-if="offsetReason" class="offset-reason">{{ offsetReason }}</div>
9493
</div>
9594
</template>
9695

9796
<style lang="scss" scoped>
98-
.offset-row {
97+
.rule-form {
9998
display: flex;
10099
flex-direction: column;
101-
gap: 6px;
102-
}
103-
104-
.offset-label {
105-
font-size: 14px;
106-
color: var(--color-text);
100+
gap: 16px;
107101
}
108102
109103
.offset-controls {
110104
display: flex;
111105
align-items: center;
112-
gap: 8px;
106+
gap: 10px;
107+
width: 100%;
108+
109+
@include forTablet {
110+
width: auto;
111+
min-width: 220px;
112+
}
113+
114+
:deep(.ab-button) {
115+
flex-shrink: 0;
116+
white-space: nowrap;
117+
}
113118
}
114119
115120
.offset-input {
116-
width: 72px;
117-
padding: 6px 10px;
118-
border: 1px solid var(--color-border);
119-
border-radius: var(--radius-sm);
120-
background: var(--color-surface);
121-
color: var(--color-text);
122-
font-size: 14px;
123-
outline: none;
124-
transition: border-color var(--transition-fast);
121+
width: 80px;
122+
flex-shrink: 0;
125123
126-
&:focus {
127-
border-color: var(--color-primary);
124+
@include forMobile {
125+
flex: 1;
126+
min-width: 60px;
128127
}
129128
}
130129
131130
.offset-reason {
132131
font-size: 12px;
133132
color: var(--color-text-secondary);
133+
padding-left: 2px;
134+
margin-top: -8px;
134135
}
135136
</style>

webui/src/components/ab-setting.vue

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ withDefaults(defineProps<AbSettingProps>(), {
77
bottomLine: false,
88
});
99
10-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
10+
1111
const data = defineModel<any>('data');
1212
</script>
1313

1414
<template>
15-
<div>
15+
<div class="setting-item">
1616
<ab-label :label="label">
1717
<AbSwitch
1818
v-if="type === 'switch'"
@@ -36,11 +36,33 @@ const data = defineModel<any>('data');
3636
v-bind="prop"
3737
/>
3838

39-
<div v-else-if="type === 'dynamic-tags'" w-full sm:max-w-200 overflow-auto pb-1>
39+
<div v-else-if="type === 'dynamic-tags'" class="dynamic-tags-wrapper">
4040
<NDynamicTags v-model:value="data" size="small"></NDynamicTags>
4141
</div>
4242
</ab-label>
4343

44-
<div v-if="bottomLine" line my-6></div>
44+
<div v-if="bottomLine" class="setting-divider"></div>
4545
</div>
4646
</template>
47+
48+
<style lang="scss" scoped>
49+
.setting-item {
50+
width: 100%;
51+
}
52+
53+
.setting-divider {
54+
height: 1px;
55+
background: var(--color-border);
56+
margin-top: 12px;
57+
}
58+
59+
.dynamic-tags-wrapper {
60+
width: 100%;
61+
overflow-x: auto;
62+
padding-bottom: 2px;
63+
64+
@include forTablet {
65+
max-width: 220px;
66+
}
67+
}
68+
</style>

webui/src/components/basic/ab-bottom-sheet.vue

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<script lang="ts" setup>
2-
import { ref, watch, computed } from 'vue';
2+
import { computed, ref } from 'vue';
33
import { usePointerSwipe } from '@vueuse/core';
44
import {
5-
TransitionRoot,
6-
TransitionChild,
75
Dialog,
86
DialogPanel,
7+
TransitionChild,
8+
TransitionRoot,
99
} from '@headlessui/vue';
1010
1111
const props = withDefaults(
@@ -69,7 +69,7 @@ function close() {
6969

7070
<template>
7171
<TransitionRoot :show="show" as="template">
72-
<Dialog @close="close" class="ab-bottom-sheet">
72+
<Dialog class="ab-bottom-sheet" @close="close">
7373
<!-- Backdrop -->
7474
<TransitionChild
7575
enter="overlay-enter-active"
@@ -125,13 +125,15 @@ function close() {
125125
&__backdrop {
126126
position: fixed;
127127
inset: 0;
128+
z-index: 100;
128129
background: rgba(0, 0, 0, 0.4);
129130
backdrop-filter: blur(4px);
130131
}
131132
132133
&__container {
133134
position: fixed;
134135
inset: 0;
136+
z-index: 101;
135137
display: flex;
136138
align-items: flex-end;
137139
justify-content: center;
@@ -140,6 +142,7 @@ function close() {
140142
141143
&__panel {
142144
position: relative;
145+
z-index: 102;
143146
width: 100%;
144147
max-width: 640px;
145148
background: var(--color-surface);

webui/src/components/basic/ab-button-multi.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,22 @@ const showSelections = ref<boolean>(false);
7070
&--big {
7171
border-radius: var(--radius-md);
7272
width: 276px;
73-
height: 55px;
74-
font-size: 24px;
73+
height: 44px;
74+
font-size: 16px;
7575
}
7676
7777
&--normal {
7878
border-radius: var(--radius-sm);
79-
width: 170px;
79+
min-width: 100px;
8080
height: 36px;
8181
font-size: 14px;
8282
}
8383
8484
&--small {
8585
border-radius: var(--radius-sm);
86-
width: 86px;
87-
height: 28px;
88-
font-size: 12px;
86+
min-width: 80px;
87+
height: 32px;
88+
font-size: 13px;
8989
}
9090
9191
&--primary {

webui/src/components/basic/ab-button.vue

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,31 +80,29 @@ const buttonSize = computed(() => {
8080
cursor: not-allowed;
8181
}
8282
83-
// Sizes - all meet 44px minimum touch target
83+
// Sizes
8484
&--big {
8585
border-radius: var(--radius-md);
86-
font-size: 18px;
86+
font-size: 16px;
8787
width: 100%;
8888
max-width: 276px;
89-
height: 55px;
89+
height: 44px;
9090
}
9191
9292
&--normal {
9393
border-radius: var(--radius-sm);
9494
font-size: 14px;
9595
width: 100%;
9696
max-width: 170px;
97-
min-height: var(--touch-target);
98-
height: 44px;
97+
height: 36px;
9998
}
10099
101100
&--small {
102101
border-radius: var(--radius-sm);
103102
font-size: 13px;
104-
min-width: 86px;
105-
min-height: var(--touch-target);
106-
height: 44px;
107-
padding: 0 16px;
103+
min-width: 80px;
104+
height: 32px;
105+
padding: 0 14px;
108106
gap: 6px;
109107
white-space: nowrap;
110108
}

0 commit comments

Comments
 (0)