表单行不再用 label 包 button 型控件
没有 for 的 label 会绑定内部第一个可关联控件。导入 ini 的「内容」行里 那是 DropFile 的按钮:悬停 textarea 会点亮投放区,点到行内空白处直接 弹出文件选择框。SelectBox 的开关按钮同理(InboundForm、RuleGroupForm、 ini 映射行),悬停整行都会点亮它。这些行改用 div,无障碍名换成控件 自己的 aria-label。ComboBox 的行保持 label——它第一个可关联控件是文本 输入框,label 转发过去正是想要的行为。
This commit is contained in:
@@ -154,13 +154,15 @@ function submit() {
|
|||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="row">
|
<!-- SelectBox 的行不用 label 包:没有 for 的 label 绑定第一个可关联控件,
|
||||||
|
正好是它的开关按钮,悬停行内任何位置都会点亮它、点空白处会展开面板 -->
|
||||||
|
<div class="row">
|
||||||
<span class="k">类型</span>
|
<span class="k">类型</span>
|
||||||
<span class="v">
|
<span class="v">
|
||||||
<SelectBox v-model="type" :options="typeOptions" />
|
<SelectBox v-model="type" :options="typeOptions" aria-label="类型" />
|
||||||
<span v-if="typeNote" class="note">{{ typeNote }}</span>
|
<span v-if="typeNote" class="note">{{ typeNote }}</span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</div>
|
||||||
|
|
||||||
<label class="row">
|
<label class="row">
|
||||||
<span class="k">端口</span>
|
<span class="k">端口</span>
|
||||||
@@ -178,7 +180,7 @@ function submit() {
|
|||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label v-for="f in requiredExtras" :key="f.key" class="row">
|
<div v-for="f in requiredExtras" :key="f.key" class="row">
|
||||||
<span class="k">{{ f.key }}</span>
|
<span class="k">{{ f.key }}</span>
|
||||||
<span class="v">
|
<span class="v">
|
||||||
<SelectBox
|
<SelectBox
|
||||||
@@ -186,11 +188,19 @@ function submit() {
|
|||||||
v-model="extras[f.key]"
|
v-model="extras[f.key]"
|
||||||
:options="f.enum.map((opt) => ({ value: String(opt) }))"
|
:options="f.enum.map((opt) => ({ value: String(opt) }))"
|
||||||
placeholder="请选择"
|
placeholder="请选择"
|
||||||
|
:aria-label="f.key"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-else
|
||||||
|
v-model="extras[f.key]"
|
||||||
|
class="mono"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off"
|
||||||
|
:aria-label="f.key"
|
||||||
/>
|
/>
|
||||||
<input v-else v-model="extras[f.key]" class="mono" type="text" autocomplete="off" />
|
|
||||||
<span v-if="f.note" class="note">{{ f.note }}</span>
|
<span v-if="f.note" class="note">{{ f.note }}</span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="dlg-foot">
|
<footer class="dlg-foot">
|
||||||
|
|||||||
@@ -111,7 +111,10 @@ function onBackdrop(event: MouseEvent) {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<label class="row">
|
<!-- 不能用 label 包:没有 for 的 label 绑定内部第一个可关联控件,
|
||||||
|
正好是 DropFile 的按钮——悬停 textarea 会点亮投放区,点到行内
|
||||||
|
空白处还会弹出文件选择框 -->
|
||||||
|
<div class="row">
|
||||||
<span class="k">内容</span>
|
<span class="k">内容</span>
|
||||||
<span class="v">
|
<span class="v">
|
||||||
<DropFile accept=".ini,.conf,.txt" @load="(_, content) => (text = content)" />
|
<DropFile accept=".ini,.conf,.txt" @load="(_, content) => (text = content)" />
|
||||||
@@ -121,9 +124,10 @@ function onBackdrop(event: MouseEvent) {
|
|||||||
rows="8"
|
rows="8"
|
||||||
placeholder="或把 ini 文本粘贴到这里"
|
placeholder="或把 ini 文本粘贴到这里"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
|
aria-label="ini 内容"
|
||||||
></textarea>
|
></textarea>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</div>
|
||||||
|
|
||||||
<template v-if="entries.length > 0">
|
<template v-if="entries.length > 0">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -138,12 +142,18 @@ function onBackdrop(event: MouseEvent) {
|
|||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<label v-for="target in targets" :key="target" class="row">
|
<!-- 同上:SelectBox 的面板开关也是 button,label 会把悬停和点击都转给它 -->
|
||||||
|
<div v-for="target in targets" :key="target" class="row">
|
||||||
<span class="k map-name" :title="target">{{ target }}</span>
|
<span class="k map-name" :title="target">{{ target }}</span>
|
||||||
<span class="v">
|
<span class="v">
|
||||||
<SelectBox v-model="mapping[target]" :options="outboundOptions" placeholder="映射到…" />
|
<SelectBox
|
||||||
|
v-model="mapping[target]"
|
||||||
|
:options="outboundOptions"
|
||||||
|
placeholder="映射到…"
|
||||||
|
:aria-label="`${target} 映射到`"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -158,28 +158,31 @@ function onBackdrop(event: MouseEvent) {
|
|||||||
</span>
|
</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="row">
|
<!-- SelectBox 的行不用 label 包:没有 for 的 label 绑定第一个可关联控件,
|
||||||
|
正好是它的开关按钮,悬停行内任何位置都会点亮它、点空白处会展开面板 -->
|
||||||
|
<div class="row">
|
||||||
<span class="k">行为</span>
|
<span class="k">行为</span>
|
||||||
<span class="v">
|
<span class="v">
|
||||||
<SelectBox v-model="behavior" :options="BEHAVIOR_OPTIONS" />
|
<SelectBox v-model="behavior" :options="BEHAVIOR_OPTIONS" aria-label="行为" />
|
||||||
<span class="note">
|
<span class="note">
|
||||||
清单每行带 DOMAIN,、IP-CIDR, 这类前缀的是 classical;纯域名列表是 domain;
|
清单每行带 DOMAIN,、IP-CIDR, 这类前缀的是 classical;纯域名列表是 domain;
|
||||||
纯 IP 网段列表是 ipcidr
|
纯 IP 网段列表是 ipcidr
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</div>
|
||||||
|
|
||||||
<label class="row">
|
<div class="row">
|
||||||
<span class="k">格式</span>
|
<span class="k">格式</span>
|
||||||
<span class="v">
|
<span class="v">
|
||||||
<SelectBox
|
<SelectBox
|
||||||
v-model="format"
|
v-model="format"
|
||||||
:options="FORMAT_OPTIONS"
|
:options="FORMAT_OPTIONS"
|
||||||
|
aria-label="格式"
|
||||||
@update:model-value="formatTouched = true"
|
@update:model-value="formatTouched = true"
|
||||||
/>
|
/>
|
||||||
<span v-if="mrsConflict" class="bad">mrs 格式只支持 domain 和 ipcidr 两种行为</span>
|
<span v-if="mrsConflict" class="bad">mrs 格式只支持 domain 和 ipcidr 两种行为</span>
|
||||||
</span>
|
</span>
|
||||||
</label>
|
</div>
|
||||||
|
|
||||||
<div class="divide" role="presentation"><span>或从文件导入</span></div>
|
<div class="divide" role="presentation"><span>或从文件导入</span></div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user