Gå til innholdet

Editoren

Skriver du TypeScript eller JSX, får du hjelp fra typene: fs. viser hele systemet, og en variant som ikke finnes stopper bygget. Se Typesikker bruk. Skriver du markup uten JavaScript, i en Go-mal, en Razor-visning, PHP eller håndskrevet HTML, ser ingen kompilator på attributtene. Da er det editoren som må si fra, og det gjør den.

Utvidelsen Fristil finnes på Marketplace. Søk etter «Fristil» under Extensions, eller kjør:

Terminal window
code --install-extension Fristil.fristil-vscode

Det du får, i HTML-filer og i malspråkene:

  • Fullføring av <fs-field>, <fs-popover> og de andre elementene, med attributtene og de lovlige verdiene. Inne i class="…" fullføres fs--klassene, og inne i et attributt en klasse tar, som data-variant på fs-button, verdiene byggefunksjonen kjenner.
  • Forklaring når du holder musa over en fs--klasse, og i HTML-filer også over et element, med lenke til komponentsiden, eller over et attributt.
  • Feilmeldinger, som røde og gule streker: et element som ikke finnes, et attributt elementet ikke har, en verdi utenfor lista, en klasse som fs-buton, og data-variant="secundary" på en knapp. <fs-field> uten kontroll eller uten ledetekst får samme beskjed som komponenten gir i nettleseren. Og det malen må skrive selv for at komponentene skal virke uten JavaScript og overleve en oppdatering fra serveren: en ledetekst som verken har for mot feltet eller står rundt det, et panel i <fs-popover> uten id, en fane som peker på et panel som ikke finnes, en fanerad uten navn, role="tab" på noe som ikke er en lenke, hjelpetekst inni <label>, data-value uten .fs-suggestion__value, en skjult feilmelding ved siden av aria-invalid="true", de utgåtte invalid, required-marker og control-id på <fs-field>, og en id komponenten lagde selv, kopiert inn fra DevTools.
  • Hurtigrettelser der det finnes ett riktig svar: lyspæra bytter fs-buton til fs-button, tar bort invalid="false" og de utgåtte attributtene, setter inn en ledetekst, gir raden et navn, og gir feltet id og ledeteksten for i ett grep, fra feltets name.
  • Snippets: skriv fs-popover og velg snippeten, og markupen fra komponentsiden står der. Id-en er et tabbestopp: skriv den én gang, så følger for på ledeteksten og href på fanene med.

Malspråkene den virker i uten innstillinger: PHP, Razor, Astro, Svelte, Vue, Twig, Blade, Jinja, Django, Handlebars, ERB, Go-maler, EJS, Liquid, Nunjucks og Edge. Der det står malsyntaks, holder den seg unna: en mal er ikke hel, og kontrollen kan stå i en partial. Lista er innstillingen fristil.languages.

Feilmeldingene og hurtigrettelsene kommer fra språkserveren, fristil lsp, den samme som Neovim og Helix bruker. Den sjekker mot Fristil-versjonen prosjektet har installert, og mot komponenter du har tatt over, se Språkserveren. Fullføringen genereres fra komponentene i repoet. Utvidelsen har sitt eget versjonsnummer, og følger ikke pakken, siden den bare endrer seg når et element, en klasse eller et attributt gjør det.

IntelliJ IDEA Ultimate og WebStorm trenger ingen utvidelse. Fra @fristil/designsystem 0.15.0 har npm-pakken med web-types.json, JetBrains sitt eget format, og IDE-en tar den i bruk så snart pakken står i package.json i prosjektet. Du får fullføring av elementene, attributtene, verdiene og fs--klassene, og forklaring med lenke til komponentsiden. Etterprøvd i IntelliJ IDEA Ultimate 2026.2.

web-types.json leses bare for filer. Står markupen i en streng, som en HTML-mal i Kotlin eller TypeScript, får du ingen forslag fra den. Det dekker pluginen Fristil: søk etter «Fristil» under Settings → Plugins → Marketplace. Den gir fullføring av fs--klassene inne i class="…" i en streng som er merket som HTML:

// language=HTML
fun lagreknapp() = """
<button class="fs-button" type="submit">Lagre</button>
"""

// language=HTML og @Language("HTML") er IntelliJs egne merker, og krever ingen avhengighet. Uten et slikt merke er strengen bare tekst for IDE-en, og da er det ingenting for pluginen å feste seg i. Fullføringen gir bare klassene, ikke elementene eller attributtene. Etterprøvd i Kotlin og TypeScript i IntelliJ IDEA Ultimate 2026.2.3.

Fra versjon 0.4.0 har pluginen live templates: skriv fs-field og trykk Tab, og markupen fra komponentsiden står der, med id-en som variabel og for som følger med. De lages fra de samme oppskriftene som snippetene i VS Code.

Fra versjon 0.3.0 gir pluginen også feilmeldingene, i HTML-filer og i merkede strenger: et element, en klasse, et attributt eller en verdi som ikke finnes, med hurtigrettelse der det finnes ett riktig svar. Sjekken er den samme Rust-kjernen som fristil sjekk og VS Code bruker, kjørt i IDE-ens egen JVM. Den trenger ikke Node eller JavaScript-støtten i IDE-en, og leter etter manifestet slik språkserveren gjør, fra fila og oppover til prosjektmappa, så komponenter du har overtatt er kjent. Fullføringen leser klassene fra det samme manifestet, så den foreslår de overtatte komponentene og aldri en klasse sjekken avviser. Et funn du vil beholde, undertrykkes med <!-- fristil-ignore-next regelnavn --> over taggen.

Feilmeldingene og hurtigrettelsene finnes som en språkserver, fristil lsp, for hver editor som snakker LSP. Den er skrevet i Rust, er den samme sjekken som fristil sjekk, og startes på den måten som passer prosjektet:

Har duKommandoen
Nodenpx @fristil/designsystem lsp
Java 17 eller nyerejava -jar fristil.jar lsp
wasmtimewasmtime run --dir=/::/ --env FRISTIL_PACKAGE=/sti/til/package fristil.wasm lsp
cargo installfristil lsp

Hvor du får fristil.jar, fristil.wasm og den kjørbare fila, står på Kommandolinjen. wasmtime ser bare mappene den får, og --dir=/::/ gir den hele filsystemet, med de samme stiene som editoren bruker. Det er den svakeste av vertene. Se Ulempene med wasmtime.

Serveren sjekker mot det prosjektet faktisk har. Den går fra mappa til fila og oppover, slik Node finner en pakke, og ser i hver mappe etter build/fristil/manifest.json, som Gradle-pluginen skriver, og så etter node_modules/@fristil/designsystem/manifest/manifest.json, den installerte pakken. Den nærmeste mappa med en av dem vinner, og den leter ikke over rota av arbeidsområdet. I et monorepo sjekkes derfor en side i apps/web mot pakken apps/web har installert. Ligger fila utenfor arbeidsområdet, som en kladdefil, eller har editoren ikke gitt noe arbeidsområde, leter den ikke fra fila i det hele tatt: da gjelder manifestet ved rota av arbeidsområdet, om det har et. Finnes ingen av dem, sjekker npx, java -jar og VS Code mot pakken de selv har med. Den kjørbare fila og wasmtime sjekker mot pakken FRISTIL_PACKAGE peker på, og uten den sjekker de ingenting og sier fra. Fila leses på nytt når den endres, så et nytt bygg eller en oppgradering når editoren uten omstart.

I Neovim 0.11 eller nyere:

vim.lsp.config("fristil", {
cmd = { "npx", "@fristil/designsystem", "lsp" },
filetypes = { "html", "htmldjango", "php", "gotmpl", "eruby", "jinja", "twig", "blade" },
root_markers = { "package.json", "build.gradle.kts", ".git" },
})
vim.lsp.enable("fristil")

I Helix, i languages.toml, ved siden av HTML-serveren:

[language-server.fristil]
command = "npx"
args = ["@fristil/designsystem", "lsp"]
[[language]]
name = "html"
language-servers = ["vscode-html-language-server", "fristil"]

Zed starter bare språkservere som en Zed-utvidelse har meldt inn, og en slik utvidelse for Fristil finnes ikke ennå.

Serveren gir funn og rettelser. Fullføring og forklaring gjør den ikke ennå, så de kommer fortsatt fra utvidelsen i VS Code, og i JetBrains fra web-types.json for filer og fra pluginen for HTML i strenger. initializationOptions kan ha manifest, en sti til et manifest som går foran de andre, og rendered: true, som sjekker hver fil som en hel side, med koblingen.

Den samme sjekken finnes uten editor. fristil sjekk leser filer, standard inn eller en adresse, og skriver hvert funn som fil:linje:kolonne: feil: melding, eller advarsel: der det er en advarsel. Ett funn gir feilkode, så den kan stå i CI:

Terminal window
npx @fristil/designsystem sjekk maler/*.html
npx @fristil/designsystem sjekk http://localhost:8080/skjema

Lager serveren HTML-en i kode, som strenger i en Kotlin-app, finnes det ingen malfil å sjekke. Da sjekker du siden serveren sender, med adressen eller med --rendret i appens egne tester. Flagg, utdata og eksempler for tester i JavaScript og Kotlin står på Kommandolinjen.

Editoren ser én fil om gangen. En ledetekst i én partial og et felt i en annen henger sammen først når siden er satt sammen. Det ser sjekk på en hel side, der den krever at hver id det pekes på finnes og at hvert felt er koblet. Se Kommandolinjen. I nettleseren sier web-komponenten fra hvis koblingen mangler. Se Markup og oppførsel.