chore(ui): tighten and center bulk delete toolbar
This commit is contained in:
@@ -1401,99 +1401,101 @@ export default function MessageSection(props: MessageSectionProps) {
|
||||
role="toolbar"
|
||||
aria-label={t("messageSection.bulkDelete.toolbarAriaLabel", { count: selectedDeleteCount() })}
|
||||
>
|
||||
<span class="message-delete-mode-token-group" aria-hidden="true">
|
||||
<span class="message-delete-mode-count message-delete-mode-count--before" title={`${tokenStats().used} tokens currently in context`}>
|
||||
{formatTokenCount(tokenStats().used)}
|
||||
<div class="message-delete-mode-toolbar-row" aria-hidden="true">
|
||||
<span class="message-delete-mode-token-group">
|
||||
<span class="message-delete-mode-count message-delete-mode-count--before" title={`${tokenStats().used} tokens currently in context`}>
|
||||
{formatTokenCount(tokenStats().used)}
|
||||
</span>
|
||||
<span class="message-delete-mode-arrow" aria-hidden="true">{"\u203A"}</span>
|
||||
<span class="message-delete-mode-count message-delete-mode-count--selection" title={`${selectedTokenTotal()} tokens selected (${selectedDeleteCount()} messages)`}>
|
||||
{formatTokenCount(selectedTokenTotal())}
|
||||
</span>
|
||||
<span class="message-delete-mode-arrow" aria-hidden="true">{"\u203A"}</span>
|
||||
<span class="message-delete-mode-count message-delete-mode-count--after" title={`${Math.max(0, tokenStats().used - selectedTokenTotal())} tokens remaining after deletion`}>
|
||||
{formatTokenCount(Math.max(0, tokenStats().used - selectedTokenTotal()))}
|
||||
</span>
|
||||
</span>
|
||||
<span class="message-delete-mode-arrow" aria-hidden="true">{"\u203A"}</span>
|
||||
<span class="message-delete-mode-count message-delete-mode-count--selection" title={`${selectedTokenTotal()} tokens selected (${selectedDeleteCount()} messages)`}>
|
||||
{formatTokenCount(selectedTokenTotal())}
|
||||
</span>
|
||||
<span class="message-delete-mode-arrow" aria-hidden="true">{"\u203A"}</span>
|
||||
<span class="message-delete-mode-count message-delete-mode-count--after" title={`${Math.max(0, tokenStats().used - selectedTokenTotal())} tokens remaining after deletion`}>
|
||||
{formatTokenCount(Math.max(0, tokenStats().used - selectedTokenTotal()))}
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="message-delete-mode-button message-delete-mode-button--delete"
|
||||
onClick={() => void deleteSelectedMessages()}
|
||||
title={t("messageSection.bulkDelete.deleteSelectedTitle")}
|
||||
aria-label={t("messageSection.bulkDelete.deleteSelectedTitle")}
|
||||
>
|
||||
<Trash class="w-4 h-4" aria-hidden="true" />
|
||||
</button>
|
||||
|
||||
<div class="message-delete-mode-menu-container">
|
||||
<button
|
||||
ref={(el) => {
|
||||
deleteMenuButtonRef = el
|
||||
}}
|
||||
type="button"
|
||||
class="message-delete-mode-button message-delete-mode-button--menu"
|
||||
onClick={() => setIsDeleteMenuOpen((prev) => !prev)}
|
||||
title={t("messageSection.bulkDelete.moreOptionsTitle")}
|
||||
aria-label={t("messageSection.bulkDelete.moreOptionsTitle")}
|
||||
class="message-delete-mode-button message-delete-mode-button--delete"
|
||||
onClick={() => void deleteSelectedMessages()}
|
||||
title={t("messageSection.bulkDelete.deleteSelectedTitle")}
|
||||
aria-label={t("messageSection.bulkDelete.deleteSelectedTitle")}
|
||||
>
|
||||
<MoreHorizontal class="w-4 h-4" aria-hidden="true" />
|
||||
<Trash class="w-4 h-4" aria-hidden="true" />
|
||||
</button>
|
||||
<Show when={isDeleteMenuOpen()}>
|
||||
<div
|
||||
|
||||
<div class="message-delete-mode-menu-container">
|
||||
<button
|
||||
ref={(el) => {
|
||||
deleteMenuRef = el
|
||||
deleteMenuButtonRef = el
|
||||
}}
|
||||
class="message-delete-mode-menu dropdown-surface"
|
||||
type="button"
|
||||
class="message-delete-mode-button message-delete-mode-button--menu"
|
||||
onClick={() => setIsDeleteMenuOpen((prev) => !prev)}
|
||||
title={t("messageSection.bulkDelete.moreOptionsTitle")}
|
||||
aria-label={t("messageSection.bulkDelete.moreOptionsTitle")}
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="dropdown-item"
|
||||
onClick={() => {
|
||||
selectAllForDeletion()
|
||||
setIsDeleteMenuOpen(false)
|
||||
<MoreHorizontal class="w-4 h-4" aria-hidden="true" />
|
||||
</button>
|
||||
<Show when={isDeleteMenuOpen()}>
|
||||
<div
|
||||
ref={(el) => {
|
||||
deleteMenuRef = el
|
||||
}}
|
||||
class="message-delete-mode-menu dropdown-surface"
|
||||
>
|
||||
{t("messageSection.bulkDelete.selectAllTitle")}
|
||||
</button>
|
||||
<div class="message-delete-mode-menu-divider" aria-hidden="true" />
|
||||
<div class="message-delete-mode-menu-row">
|
||||
<span class="message-delete-mode-menu-label">
|
||||
{t("messageSection.bulkDelete.selectionModeLabel")}
|
||||
</span>
|
||||
<div class="message-delete-mode-menu-toggle">
|
||||
<button
|
||||
type="button"
|
||||
class="message-delete-mode-menu-toggle-button"
|
||||
data-mode="all"
|
||||
data-active={selectionMode() === "all"}
|
||||
onClick={() => applySelectionMode("all")}
|
||||
>
|
||||
{t("messageSection.bulkDelete.selectionModeAll")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="message-delete-mode-menu-toggle-button"
|
||||
data-mode="tools"
|
||||
data-active={selectionMode() === "tools"}
|
||||
onClick={() => applySelectionMode("tools")}
|
||||
>
|
||||
{t("messageSection.bulkDelete.selectionModeTools")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="dropdown-item"
|
||||
onClick={() => {
|
||||
selectAllForDeletion()
|
||||
setIsDeleteMenuOpen(false)
|
||||
}}
|
||||
>
|
||||
{t("messageSection.bulkDelete.selectAllTitle")}
|
||||
</button>
|
||||
<div class="message-delete-mode-menu-divider" aria-hidden="true" />
|
||||
<div class="message-delete-mode-menu-row">
|
||||
<span class="message-delete-mode-menu-label">
|
||||
{t("messageSection.bulkDelete.selectionModeLabel")}
|
||||
</span>
|
||||
<div class="message-delete-mode-menu-toggle">
|
||||
<button
|
||||
type="button"
|
||||
class="message-delete-mode-menu-toggle-button"
|
||||
data-mode="all"
|
||||
data-active={selectionMode() === "all"}
|
||||
onClick={() => applySelectionMode("all")}
|
||||
>
|
||||
{t("messageSection.bulkDelete.selectionModeAll")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="message-delete-mode-menu-toggle-button"
|
||||
data-mode="tools"
|
||||
data-active={selectionMode() === "tools"}
|
||||
onClick={() => applySelectionMode("tools")}
|
||||
>
|
||||
{t("messageSection.bulkDelete.selectionModeTools")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="message-delete-mode-button message-delete-mode-button--cancel"
|
||||
onClick={clearDeleteMode}
|
||||
title={t("messageSection.bulkDelete.cancelTitle")}
|
||||
aria-label={t("messageSection.bulkDelete.cancelTitle")}
|
||||
>
|
||||
<X class="w-4 h-4" aria-hidden="true" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="message-delete-mode-button message-delete-mode-button--cancel"
|
||||
onClick={clearDeleteMode}
|
||||
title={t("messageSection.bulkDelete.cancelTitle")}
|
||||
aria-label={t("messageSection.bulkDelete.cancelTitle")}
|
||||
>
|
||||
<X class="w-4 h-4" aria-hidden="true" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="message-delete-mode-hint-row keyboard-hints" aria-hidden="true">
|
||||
<Kbd shortcut="cmd+click" />
|
||||
|
||||
@@ -92,9 +92,9 @@ export const messagingMessages = {
|
||||
"messageSection.bulkDelete.selectionModeLabel": "Selección",
|
||||
"messageSection.bulkDelete.selectionModeAll": "Todo",
|
||||
"messageSection.bulkDelete.selectionModeTools": "Solo herramientas",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "alternar",
|
||||
"messageSection.bulkDelete.selectionHint.range": "rango",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "limpiar",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "Seleccionar elemento",
|
||||
"messageSection.bulkDelete.selectionHint.range": "Seleccionar rango",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "Borrar selección",
|
||||
"messageSection.bulkDelete.cancelTitle": "Cancelar selección",
|
||||
"messageSection.bulkDelete.failedTitle": "Error al eliminar",
|
||||
"messageSection.bulkDelete.failedMessage": "No se pudieron eliminar los elementos seleccionados",
|
||||
|
||||
@@ -92,9 +92,9 @@ export const messagingMessages = {
|
||||
"messageSection.bulkDelete.selectionModeLabel": "Sélection",
|
||||
"messageSection.bulkDelete.selectionModeAll": "Tous",
|
||||
"messageSection.bulkDelete.selectionModeTools": "Outils uniquement",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "basculer",
|
||||
"messageSection.bulkDelete.selectionHint.range": "plage",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "effacer",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "Selectionner un element",
|
||||
"messageSection.bulkDelete.selectionHint.range": "Selectionner une plage",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "Effacer la selection",
|
||||
"messageSection.bulkDelete.cancelTitle": "Annuler la sélection",
|
||||
"messageSection.bulkDelete.failedTitle": "Échec de suppression",
|
||||
"messageSection.bulkDelete.failedMessage": "Impossible de supprimer les éléments sélectionnés",
|
||||
|
||||
@@ -92,9 +92,9 @@ export const messagingMessages = {
|
||||
"messageSection.bulkDelete.selectionModeLabel": "選択",
|
||||
"messageSection.bulkDelete.selectionModeAll": "すべて",
|
||||
"messageSection.bulkDelete.selectionModeTools": "ツールのみ",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "切り替え",
|
||||
"messageSection.bulkDelete.selectionHint.range": "範囲",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "クリア",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "項目を選択",
|
||||
"messageSection.bulkDelete.selectionHint.range": "範囲を選択",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "選択を解除",
|
||||
"messageSection.bulkDelete.cancelTitle": "選択をキャンセル",
|
||||
"messageSection.bulkDelete.failedTitle": "削除に失敗しました",
|
||||
"messageSection.bulkDelete.failedMessage": "選択した項目の削除に失敗しました",
|
||||
|
||||
@@ -92,9 +92,9 @@ export const messagingMessages = {
|
||||
"messageSection.bulkDelete.selectionModeLabel": "Выбор",
|
||||
"messageSection.bulkDelete.selectionModeAll": "Все",
|
||||
"messageSection.bulkDelete.selectionModeTools": "Только инструменты",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "переключить",
|
||||
"messageSection.bulkDelete.selectionHint.range": "диапазон",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "очистить",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "Выбрать элемент",
|
||||
"messageSection.bulkDelete.selectionHint.range": "Выбрать диапазон",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "Очистить выбор",
|
||||
"messageSection.bulkDelete.cancelTitle": "Отменить выбор",
|
||||
"messageSection.bulkDelete.failedTitle": "Ошибка удаления",
|
||||
"messageSection.bulkDelete.failedMessage": "Не удалось удалить выбранные элементы",
|
||||
|
||||
@@ -92,9 +92,9 @@ export const messagingMessages = {
|
||||
"messageSection.bulkDelete.selectionModeLabel": "选择",
|
||||
"messageSection.bulkDelete.selectionModeAll": "全部",
|
||||
"messageSection.bulkDelete.selectionModeTools": "仅工具",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "切换",
|
||||
"messageSection.bulkDelete.selectionHint.range": "范围",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "清除",
|
||||
"messageSection.bulkDelete.selectionHint.toggle": "选择项目",
|
||||
"messageSection.bulkDelete.selectionHint.range": "选择范围",
|
||||
"messageSection.bulkDelete.selectionHint.clear": "清除选择",
|
||||
"messageSection.bulkDelete.cancelTitle": "取消选择",
|
||||
"messageSection.bulkDelete.failedTitle": "删除失败",
|
||||
"messageSection.bulkDelete.failedMessage": "无法删除已选择的项目",
|
||||
|
||||
@@ -11,20 +11,29 @@
|
||||
|
||||
.message-delete-mode-toolbar {
|
||||
position: absolute;
|
||||
right: 5rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 1rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 10px;
|
||||
background: color-mix(in oklab, var(--surface-base) 62%, var(--accent-primary));
|
||||
border: 1px solid var(--accent-primary);
|
||||
/* Match other popups (dropdown-surface / panels) */
|
||||
background-color: var(--surface-base);
|
||||
border: 1px solid var(--border-base);
|
||||
border-radius: 12px;
|
||||
z-index: 50;
|
||||
box-shadow:
|
||||
0 0 0 1px color-mix(in oklab, var(--accent-primary) 25%, transparent),
|
||||
0 8px 24px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: var(--panel-shadow-strong);
|
||||
width: max-content;
|
||||
max-width: min(80vw, 560px);
|
||||
}
|
||||
|
||||
.message-delete-mode-toolbar-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.message-delete-mode-token-group {
|
||||
@@ -202,7 +211,6 @@
|
||||
}
|
||||
|
||||
.message-delete-mode-hint-row {
|
||||
flex: 1 0 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -211,10 +219,11 @@
|
||||
font-size: 10px;
|
||||
color: var(--text-muted);
|
||||
user-select: none;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.message-delete-mode-hint-text {
|
||||
white-space: nowrap;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.message-delete-mode-hint-sep {
|
||||
|
||||
Reference in New Issue
Block a user