SHA256
UI v4: новый стиль по макету V3/V4 и доводка экранов
Палитра «Сияние» по умолчанию, новые роли цветов. Лента канала: плоские записи, ряд действий с равным шагом иконок, дата у записи. Обсуждение со строкой ввода, личный чат, шторки. Вход и регистрация: стартовый экран (надпись «СИЯНИЕ», сияние мандалы), настройки входа со статусами серверов, статус логина в одну строку, вход с другого устройства (код, таймер, шаги), сохранение ключей с переключателями. Корневые разделы – заголовок по центру; фильтр чатов – переключатель; уведомления – список как в чатах; фото – просмотр на весь экран. Общее: один зазор под шапкой (--page-top-gap), переключатели высотой с поле ввода, второстепенные кнопки по одной роли (в том числе на экранах устройств и серверов), иконки только из ui-icon.js, полоса прокрутки скрыта, среднее тире в текстах интерфейса. Что нужно от сервера и разработчика – docs/UI-Design/UI-v4-for-dev.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -208,23 +208,33 @@ export function render({ navigate, chrome }) {
|
||||
];
|
||||
let reloadForFilter = () => {};
|
||||
const filterRow = document.createElement('div');
|
||||
filterRow.className = 'chip-row chip-row--bleed dm-filter-row';
|
||||
filterRow.setAttribute('role', 'toolbar');
|
||||
filterRow.className = 'tabs tabs--auto tabs--dense dm-filter-row';
|
||||
filterRow.setAttribute('role', 'radiogroup');
|
||||
filterRow.setAttribute('aria-label', 'Фильтр чатов');
|
||||
const selectFilter = (value) => {
|
||||
if (currentChatFilter === value) return;
|
||||
currentChatFilter = value;
|
||||
filterRow.querySelectorAll('.tab-btn').forEach((el) => el.setAttribute('aria-checked', String(el.dataset.filter === value)));
|
||||
reloadForFilter();
|
||||
};
|
||||
CHAT_FILTERS.forEach(([value, label]) => {
|
||||
const chip = document.createElement('button');
|
||||
chip.type = 'button';
|
||||
chip.className = 'chip';
|
||||
chip.dataset.filter = value;
|
||||
chip.textContent = label;
|
||||
chip.setAttribute('aria-pressed', String(value === currentChatFilter));
|
||||
chip.addEventListener('click', () => {
|
||||
if (currentChatFilter === value) return;
|
||||
currentChatFilter = value;
|
||||
filterRow.querySelectorAll('.chip').forEach((el) => el.setAttribute('aria-pressed', String(el.dataset.filter === value)));
|
||||
reloadForFilter();
|
||||
});
|
||||
filterRow.append(chip);
|
||||
const button = document.createElement('button');
|
||||
button.type = 'button';
|
||||
button.className = 'tab-btn';
|
||||
button.dataset.filter = value;
|
||||
button.textContent = label;
|
||||
button.setAttribute('role', 'radio');
|
||||
button.setAttribute('aria-checked', String(value === currentChatFilter));
|
||||
button.addEventListener('click', () => selectFilter(value));
|
||||
filterRow.append(button);
|
||||
});
|
||||
filterRow.addEventListener('keydown', (event) => {
|
||||
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return;
|
||||
const index = CHAT_FILTERS.findIndex(([value]) => value === currentChatFilter);
|
||||
const next = CHAT_FILTERS[(index + (event.key === 'ArrowRight' ? 1 : -1) + CHAT_FILTERS.length) % CHAT_FILTERS.length][0];
|
||||
selectFilter(next);
|
||||
filterRow.querySelector(`[data-filter="${next}"]`)?.focus();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
const head = createTopBar({
|
||||
|
||||
Reference in New Issue
Block a user