From 5eb4d9117c6d837ac3c9410c72efdf727ab30393 Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Mon, 15 Jun 2026 16:30:32 +0200 Subject: [PATCH] chore(front): apply biome formatter --- static/css/base/variables.css | 57 ++++++++++++++-------------- static/css/views/auth.css | 4 +- static/js/app/filesView.js | 4 +- static/js/app/navigation.js | 4 +- static/js/app/ui.js | 9 +---- static/js/app/uiNotifications.js | 2 +- static/js/components/resourceList.js | 3 +- static/js/core/formatters.js | 9 +---- static/js/core/icons.js | 5 +-- static/js/features/auth/auth.js | 13 ++----- static/js/views/profile/profile.js | 2 +- 11 files changed, 44 insertions(+), 68 deletions(-) diff --git a/static/css/base/variables.css b/static/css/base/variables.css index 9dd5fab9..541f09c6 100644 --- a/static/css/base/variables.css +++ b/static/css/base/variables.css @@ -34,11 +34,11 @@ /* ── Layout shell ──────────────────────────────────────────── */ /* Fluid sidebar: tracks viewport but clamped to a sane band. */ --sidebar-width: clamp(220px, 18vw, 280px); - --sidebar-width-min: 200px; /* resizable rail floor (Fase 1) */ - --sidebar-width-max: 320px; /* resizable rail ceiling (Fase 1) */ - --sidebar-width-collapsed: 72px; /* icon-rail mode (Fase 1) */ - --gutter: var(--space-6); /* shared topbar/content horizontal gutter (drops to 16px on phones) */ - --grid-card-min: 200px; /* min width of a grid card (tightens on phones) */ + --sidebar-width-min: 200px; /* resizable rail floor (Fase 1) */ + --sidebar-width-max: 320px; /* resizable rail ceiling (Fase 1) */ + --sidebar-width-collapsed: 72px; /* icon-rail mode (Fase 1) */ + --gutter: var(--space-6); /* shared topbar/content horizontal gutter (drops to 16px on phones) */ + --grid-card-min: 200px; /* min width of a grid card (tightens on phones) */ /* ── Spacing — 4px grid ────────────────────────────────────── */ /* Direct steps are multiples of 4; half-steps (0-5/1-5/2-5/3-5) @@ -88,18 +88,18 @@ /* Modular size scale in rem (root = 16px) so it honors user zoom. * --text-base (14px) is the app body default. */ - --text-2xs: 0.6875rem; /* 11px */ - --text-xs: 0.75rem; /* 12px */ - --text-sm: 0.8125rem; /* 13px */ - --text-base: 0.875rem; /* 14px */ - --text-md: 1rem; /* 16px */ - --text-lg: 1.125rem; /* 18px */ - --text-xl: 1.25rem; /* 20px */ - --text-2xl: 1.5rem; /* 24px */ - --text-3xl: 1.75rem; /* 28px */ - --text-4xl: 2rem; /* 32px */ - --text-5xl: 2.5rem; /* 40px */ - --text-6xl: 3rem; /* 48px */ + --text-2xs: 0.6875rem; /* 11px */ + --text-xs: 0.75rem; /* 12px */ + --text-sm: 0.8125rem; /* 13px */ + --text-base: 0.875rem; /* 14px */ + --text-md: 1rem; /* 16px */ + --text-lg: 1.125rem; /* 18px */ + --text-xl: 1.25rem; /* 20px */ + --text-2xl: 1.5rem; /* 24px */ + --text-3xl: 1.75rem; /* 28px */ + --text-4xl: 2rem; /* 32px */ + --text-5xl: 2.5rem; /* 40px */ + --text-6xl: 3rem; /* 48px */ /* Line-heights (leading) — unitless ratios. */ --leading-none: 1; @@ -189,8 +189,8 @@ /* ── Density — comfortable (default) vs compact ────────────── */ /* Gated by html[data-density="compact"] below. Consumed by list rows * and controls in Fase 1. */ - --density-row-py: var(--space-3); /* 12px */ - --density-row-px: var(--space-3-5); /* 14px */ + --density-row-py: var(--space-3); /* 12px */ + --density-row-px: var(--space-3-5); /* 14px */ --density-gap: var(--space-3); --density-control-h: 40px; @@ -218,14 +218,14 @@ * an alias so no consumer breaks (migration to the canonical names → Fase 1). * Each tier clears WCAG AA 4.5:1 on #fff AND the page bg, light and dark. The * muted/faint/placeholder tiers used to FAIL (2.3–4.0:1) and are now darkened. */ - --color-text: light-dark(#2d3748, #e2e8f0); /* primary body */ - --color-text-heading: light-dark(#1e293b, #f1f5f9); /* headings */ - --color-text-secondary: light-dark(#475569, #cbd5e1); /* strong secondary */ + --color-text: light-dark(#2d3748, #e2e8f0); /* primary body */ + --color-text-heading: light-dark(#1e293b, #f1f5f9); /* headings */ + --color-text-secondary: light-dark(#475569, #cbd5e1); /* strong secondary */ /* muted/subtle/faint converge: AA 4.5:1 on the grayish page/muted bgs AND * on the lighter dark hover bg leaves only a narrow passing window. */ - --color-text-muted: light-dark(#5e6a78, #9fadbe); /* muted */ - --color-text-subtle: light-dark(#5e6a78, #9fadbe); /* subtle */ - --color-text-faint: light-dark(#5e6a78, #9fadbe); /* faintest still-AA */ + --color-text-muted: light-dark(#5e6a78, #9fadbe); /* muted */ + --color-text-subtle: light-dark(#5e6a78, #9fadbe); /* subtle */ + --color-text-faint: light-dark(#5e6a78, #9fadbe); /* faintest still-AA */ /* legacy aliases → one of the tiers above */ --color-text-dark: var(--color-text-secondary); --color-text-dim: var(--color-text-secondary); @@ -274,8 +274,7 @@ radial-gradient(55% 55% at 95% 98%, var(--color-accent-glow), transparent 58%), radial-gradient(48% 48% at 88% 12%, var(--color-accent-glow-soft), transparent 55%), radial-gradient(50% 45% at 6% 92%, var(--color-accent-glow-soft), transparent 55%), - radial-gradient(78% 64% at 50% 33%, var(--color-bg-surface), transparent 70%), - var(--color-bg-page); + radial-gradient(78% 64% at 50% 33%, var(--color-bg-surface), transparent 70%), var(--color-bg-page); /* Desaturated fractal-noise grain — kills gradient banding and adds a tactile, "expensive" film. No colour inside the data-URI (token-safe); applied via a low-opacity overlay pseudo-element. */ @@ -676,8 +675,8 @@ html[data-color-scheme="dark"] { /* Compact density — tighter rows/controls. Toggled by writing * data-density="compact" on ; consumed by list/control CSS in Fase 1. */ html[data-density="compact"] { - --density-row-py: var(--space-2); /* 8px */ - --density-row-px: var(--space-2-5); /* 10px */ + --density-row-py: var(--space-2); /* 8px */ + --density-row-px: var(--space-2-5); /* 10px */ --density-gap: var(--space-2); --density-control-h: 32px; } diff --git a/static/css/views/auth.css b/static/css/views/auth.css index 53e0383c..526eecf7 100644 --- a/static/css/views/auth.css +++ b/static/css/views/auth.css @@ -389,7 +389,9 @@ border-color: transparent; color: var(--color-on-accent); /* Subtle halo lifts the active step off the connector track. */ - box-shadow: 0 0 0 4px var(--color-accent-ring), 0 4px 12px var(--color-accent-shadow); + box-shadow: + 0 0 0 4px var(--color-accent-ring), + 0 4px 12px var(--color-accent-shadow); } .step-title { diff --git a/static/js/app/filesView.js b/static/js/app/filesView.js index a28586bf..993db469 100644 --- a/static/js/app/filesView.js +++ b/static/js/app/filesView.js @@ -455,9 +455,7 @@ async function loadFiles(options = { insertHistory: true }) { ? '
' : '
'; const wrapper = isList ? 'files-skeleton' : 'files-grid-view files-skeleton'; - ui.showError( - `
${cell.repeat(8)}
` - ); + ui.showError(`
${cell.repeat(8)}
`); }, 100); // A temporary guard: _loadPage sets _loading itself, but we need to diff --git a/static/js/app/navigation.js b/static/js/app/navigation.js index 757abd1c..ecf5304e 100644 --- a/static/js/app/navigation.js +++ b/static/js/app/navigation.js @@ -111,9 +111,7 @@ function initSidebarToggle() { // Trap Tab focus inside the open drawer (mobile). sidebar.addEventListener('keydown', (e) => { if (e.key !== 'Tab' || !sidebar.classList.contains('open')) return; - const f = /** @type {NodeListOf} */ ( - sidebar.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])') - ); + const f = /** @type {NodeListOf} */ (sidebar.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])')); if (!f.length) return; const first = f[0]; const last = f[f.length - 1]; diff --git a/static/js/app/ui.js b/static/js/app/ui.js index c5aa0c93..6201cacb 100644 --- a/static/js/app/ui.js +++ b/static/js/app/ui.js @@ -16,7 +16,7 @@ import { wopiEditor } from '../features/files/wopiEditor.js'; import { recent } from '../features/library/recent.js'; import { buildBatchDownloadUrl } from '../utils/download.js'; import { positionMenu } from '../utils/menuPosition.js'; -import { loadFiles, filesView } from './filesView.js'; +import { filesView, loadFiles } from './filesView.js'; import { updateHistory } from './main.js'; import { activateFilesUI, switchToFilesSection, syncViewContainers } from './navigation.js'; import { app } from './state.js'; @@ -1057,12 +1057,7 @@ const ui = { const active = btn.dataset.sortField === field; btn.classList.toggle('is-active', active); const colName = btn.querySelector('span')?.textContent || ''; - btn.setAttribute( - 'aria-label', - active - ? `${colName}: ${reversed ? i18n.t('sort.desc', 'descending') : i18n.t('sort.asc', 'ascending')}` - : colName - ); + btn.setAttribute('aria-label', active ? `${colName}: ${reversed ? i18n.t('sort.desc', 'descending') : i18n.t('sort.asc', 'ascending')}` : colName); const arrow = btn.querySelector('.list-header-sort__arrow'); if (arrow) { arrow.classList.toggle('hidden', !active); diff --git a/static/js/app/uiNotifications.js b/static/js/app/uiNotifications.js index f63819d7..a4a86862 100644 --- a/static/js/app/uiNotifications.js +++ b/static/js/app/uiNotifications.js @@ -3,8 +3,8 @@ * Isolates notification rendering policy from ui.js. */ -import { notifications } from '../core/notifications.js'; import { announce } from '../core/liveRegion.js'; +import { notifications } from '../core/notifications.js'; const uiNotifications = { /** diff --git a/static/js/components/resourceList.js b/static/js/components/resourceList.js index 3d66ed3b..0b135ae3 100644 --- a/static/js/components/resourceList.js +++ b/static/js/components/resourceList.js @@ -47,8 +47,7 @@ const JUST_ADDED_KEY = '__oxicloud_just_added__'; */ function gridMetaDate(value) { if (!value) return ''; - const date = - value instanceof Date ? value : new Date(typeof value === 'number' && value < 1e12 ? value * 1000 : value); + const date = value instanceof Date ? value : new Date(typeof value === 'number' && value < 1e12 ? value * 1000 : value); if (Number.isNaN(date.getTime())) return ''; const ageDays = (Date.now() - date.getTime()) / 86_400_000; return ageDays > 30 ? formatDateShort(value) : formatRelativeTime(value); diff --git a/static/js/core/formatters.js b/static/js/core/formatters.js index 63892155..aea4e4e2 100644 --- a/static/js/core/formatters.js +++ b/static/js/core/formatters.js @@ -27,9 +27,7 @@ function formatFileSize(bytes) { const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); - const num = new Intl.NumberFormat(i18n.getCurrentLocale(), { maximumFractionDigits: 2 }).format( - bytes / k ** i - ); + const num = new Intl.NumberFormat(i18n.getCurrentLocale(), { maximumFractionDigits: 2 }).format(bytes / k ** i); return `${num} ${sizes[i]}`; } @@ -89,10 +87,7 @@ function formatDateShort(value) { */ function formatRelativeTime(value) { if (!value) return ''; - const date = - value instanceof Date - ? value - : new Date(typeof value === 'number' && value < 1e12 ? value * 1000 : value); + const date = value instanceof Date ? value : new Date(typeof value === 'number' && value < 1e12 ? value * 1000 : value); if (Number.isNaN(date.getTime())) return String(value); const diffSec = Math.round((date.getTime() - Date.now()) / 1000); const abs = Math.abs(diffSec); diff --git a/static/js/core/icons.js b/static/js/core/icons.js index d2375c52..13219e4c 100644 --- a/static/js/core/icons.js +++ b/static/js/core/icons.js @@ -524,10 +524,7 @@ const OxiIcons = { 'M384 96c0-35.3 28.7-64 64-64s64 28.7 64 64l0 32c0 17.7 14.3 32 32 32s32-14.3 32-32l0-32c0-70.7-57.3-128-128-128S320 25.3 320 96l0 64-160 0c-35.3 0-64 28.7-64 64l0 224c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-224c0-35.3-28.7-64-64-64l-32 0 0-64z' ], - 'adjust': [ - 512, - 'M448 256c0-106-86-192-192-192l0 384c106 0 192-86 192-192zM0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0z' - ], + adjust: [512, 'M448 256c0-106-86-192-192-192l0 384c106 0 192-86 192-192zM0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0z'] }; // Icon CSS is now in /css/components/icons.css (loaded via main.css). diff --git a/static/js/features/auth/auth.js b/static/js/features/auth/auth.js index 08ea2e30..a32c6661 100644 --- a/static/js/features/auth/auth.js +++ b/static/js/features/auth/auth.js @@ -850,10 +850,7 @@ function initPasswordToggles() { const sync = () => { const shown = input.type === 'text'; btn.setAttribute('aria-pressed', String(shown)); - btn.setAttribute( - 'aria-label', - shown ? i18n.t('auth.hidePassword', 'Hide password') : i18n.t('auth.showPassword', 'Show password') - ); + btn.setAttribute('aria-label', shown ? i18n.t('auth.hidePassword', 'Hide password') : i18n.t('auth.showPassword', 'Show password')); }; sync(); btn.addEventListener('click', () => { @@ -930,9 +927,7 @@ function initPasswordMatch(passId, confirmId, indicatorId) { } const ok = pass.value === confirmEl.value; out.className = `auth-match show ${ok ? 'auth-match--ok' : 'auth-match--bad'}`; - out.textContent = ok - ? i18n.t('auth.passwordsMatch', 'Passwords match') - : i18n.t('auth.passwords_mismatch', "Passwords don't match"); + out.textContent = ok ? i18n.t('auth.passwordsMatch', 'Passwords match') : i18n.t('auth.passwords_mismatch', "Passwords don't match"); }; pass.addEventListener('input', update); confirmEl.addEventListener('input', update); @@ -1107,9 +1102,7 @@ if (isLoginPage && loginForm) { const username = inputVal('login-username'); const password = inputVal('login-password'); - const loginSubmit = /** @type {HTMLButtonElement | null} */ ( - document.getElementById('login-submit') - ); + const loginSubmit = /** @type {HTMLButtonElement | null} */ (document.getElementById('login-submit')); loginSubmit?.classList.add('is-loading'); loginSubmit?.setAttribute('aria-busy', 'true'); if (loginSubmit) loginSubmit.disabled = true; diff --git a/static/js/views/profile/profile.js b/static/js/views/profile/profile.js index 79ef93e4..8faabc7c 100644 --- a/static/js/views/profile/profile.js +++ b/static/js/views/profile/profile.js @@ -1,7 +1,7 @@ import { getCsrfHeaders } from '../../core/csrf.js'; import { installFetchInterceptor } from '../../core/fetchWrapper.js'; -import { i18n } from '../../core/i18n.js'; import { formatRelativeTime } from '../../core/formatters.js'; +import { i18n } from '../../core/i18n.js'; import { oxiIconsInit } from '../../core/icons.js'; import { resizeImageToDataUrl } from '../../utils/imageResize.js';