- update the vendored `modern-normalize` to v3.0.1 - require descriptions for lint disables in TS and CSS, same as we already have in Go. - disable core rules covered by `regexp/*` and `unicorn/*`, and ones that cannot fire - stop applying vitest rules to the playwright files in `tests/e2e` - enable 7 stylelint rules, mostly `no-unknown` and `no-invalid` checks - drop 2 unnecessary vendor prefixes (safari v17+, chrome v120+) - look up ids via `querySelector` with `CSS.escape` instead of `getElementById` - remove stale doc about `@ts-expect-error`, it's forbidden - misc dev doc fixes Every declaration that `modern-normalize` v3 removes was checked against chromium, webkit and firefox defaults first. The `hr` color and the `:-moz-focusring` outline are kept as documented deviations, dropping those does change rendering. --------- Signed-off-by: silverwind <me@silverwind.io> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
4.3 KiB
Frontend development guidelines
This document covers frontend-specific architecture and contribution expectations. For the general workflow see CONTRIBUTING.md, and for building and testing see development.md and testing.md.
Background
The frontend uses Vue 3, hard-forked Fomantic-UI (built on jQuery) and Tailwind CSS. Pages are rendered with Go HTML templates. Source files live in:
web_src/css/: CSS stylesweb_src/js/: JavaScript and TypeScriptweb_src/js/components/: Vue componentsweb_src/js/features/: feature modules wired up at page loadtemplates/: Go HTML templates
Dependencies
Frontend dependencies are managed with pnpm. The same rules as
for backend dependencies apply, except the
relevant files are package.json and pnpm-lock.yaml, and new versions must always
reference an existing published version.
Framework usage
Mixing frameworks arbitrarily makes code hard to maintain. Recommended combinations:
- Vue3
- Vanilla JavaScript
- Fomantic-UI (jQuery), deprecated, we vendored a specific version with a lot of changes.
Avoid combinations such as Vue with Fomantic-UI. Vue components may reuse Fomantic-UI CSS classes for visual consistency. Use Go templates for simple or SEO-relevant pages and Vue for complex, interactive pages. Gitea uses Vue 3 without JSX to keep HTML and JavaScript separate.
Note
Fomantic-UI is not an accessibility-friendly framework. Gitea patches some ARIA behavior, but accessibility work is ongoing — prefer semantic HTML and test keyboard/screen-reader behavior where you can.
Gitea-specific conventions
- Keep features in their own files or directories.
- Use kebab-case for HTML
ids and classes with 2-3 feature keywords. - Prefix classes to avoid short-name conflicts between different frameworks.
- Our framework can automatically link "input" and "label" if they are the children of a
.fieldelement, no need to writeid/forattributes for them unless there are reasons to do so. - Create a new class name when overriding framework styles instead of editing the framework's own classes, or fix the framework's source to fix all cases.
- Prefer semantic elements such as
<button>over generic<div>s. - Avoid
!important; when it is unavoidable, document why. - Prefix custom DOM events with
ce-.
CSS
Prefer Tailwind utility classes with the tw- prefix, and the flex-* layout
helpers over per-child margins. Gitea also ships a small set of custom helpers:
gt- for general helpers and g- for framework-level helpers (see
web_src/css/helpers.css); use these only when a Tailwind utility does not exist.
Write class attributes as a single readable unit in templates:
<div class="flex-text-inline {{if .IsFoo}}tw-hidden{{end}}"></div>
TypeScript
- Use
import typefor type-only imports. - Use the
!non-null assertion (rather than?./??) when a value is known to always exist. - Only mark a function
asyncwhen it actually usesawaitor returns aPromise. Avoid async event listeners; if unavoidable, calle.preventDefault()before the firstawait.
Data fetching
Use the GET, POST, PUT, PATCH, and DELETE wrappers from
web_src/js/modules/fetch.ts.
Prefer to use our fetch-action.ts framework
for form submissions, button clicks and network requests, which provides a consistent UX and error handling.
DOM attributes
Avoid node.dataset because of its camel-casing behavior; use node.getAttribute
in new code. Never bind user-provided data directly onto DOM nodes.
Showing and hiding elements
- In Vue, use
v-ifandv-show. If an element contains unmanaged DOM, usev-showto avoid losing the DOM state. - In Go templates and plain JavaScript, use the
.tw-hiddenclass together with theshowElem(),hideElem(), andtoggleElem()helpers fromweb_src/js/utils/dom.ts.
UI component gallery
When running Gitea in development mode, standardized UI components are available at
/devtest (for example http://localhost:3000/devtest). These pages are also used
by the e2e tests.