Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 56 additions & 54 deletions doc-site/.vitepress/theme/components/NveTableDemo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -187,61 +187,63 @@ const toggleColumn = (header: TableHeader<Country>) => {
</script>

<template>
<div class="nve-table-demo">
<nve-accordion-item variant="secondary" :open="true">
<div slot="summary">Slå av og på kolonner</div>
<div class="column-toggles">
<nve-checkbox
v-for="col in tableHeaders"
:key="col.key"
:checked="!col.hidden"
@sl-change="() => toggleColumn(col)"
>
{{ col.title }}
</nve-checkbox>
</div>
</nve-accordion-item>
<NveTable
:headers="tableHeaders"
:data="countries"
striped
:page-size="15"
:initial-sort="{ field: 'name', direction: 'ASC' }"
:filter-function="tableFilter"
:item-id="(country: Country) => country.countryCode"
>
<template #filterbutton>
<nve-button variant="ghost" @click="filterOpen = !filterOpen">
<nve-icon slot="prefix" name="filter_alt" />
Filtrer
</nve-button>
</template>
<template #subheader>
<Transition :duration="400" name="filter">
<div v-if="filterOpen" class="filter-wrapper">
<div class="filter">
<nve-checkbox-group
:value="selectedContinents"
orientation="horizontal"
:[`selectedValues`]="selectedContinents"
ref="continents-checkbox-group"
@input="updateContinents"
>
<nve-checkbox v-for="cont of allContinents" :key="cont" :value="cont">
{{ cont }}
</nve-checkbox>
</nve-checkbox-group>
<ClientOnly>
<div class="nve-table-demo">
<nve-accordion-item variant="secondary" :open="true">
<div slot="summary">Slå av og på kolonner</div>
<div class="column-toggles">
<nve-checkbox
v-for="col in tableHeaders"
:key="col.key"
:checked="!col.hidden"
@sl-change="() => toggleColumn(col)"
>
{{ col.title }}
</nve-checkbox>
</div>
</nve-accordion-item>
<NveTable
:headers="tableHeaders"
:data="countries"
striped
:page-size="15"
:initial-sort="{ field: 'name', direction: 'ASC' }"
:filter-function="tableFilter"
:item-id="(country: Country) => country.countryCode"
>
<template #filterbutton>
<nve-button variant="ghost" @click="filterOpen = !filterOpen">
<nve-icon slot="prefix" name="filter_alt" />
Filtrer
</nve-button>
</template>
<template #subheader>
<Transition :duration="400" name="filter">
<div v-if="filterOpen" class="filter-wrapper">
<div class="filter">
<nve-checkbox-group
:value="selectedContinents"
orientation="horizontal"
:[`selectedValues`]="selectedContinents"
ref="continents-checkbox-group"
@input="updateContinents"
>
<nve-checkbox v-for="cont of allContinents" :key="cont" :value="cont">
{{ cont }}
</nve-checkbox>
</nve-checkbox-group>
</div>
</div>
</div>
</Transition>
</template>
<template #[`item.countryCode`]="row">
<span class="country-code">
<img :src="`https://hatscripts.github.io/circle-flags/flags/${row.value.toLowerCase()}.svg`" width="32" />
</span>
</template>
</NveTable>
</div>
</Transition>
</template>
<template #[`item.countryCode`]="row">
<span class="country-code">
<img :src="`https://hatscripts.github.io/circle-flags/flags/${row.value.toLowerCase()}.svg`" width="32" />
</span>
</template>
</NveTable>
</div>
</ClientOnly>
</template>

<style scoped>
Expand Down
185 changes: 185 additions & 0 deletions doc-site/components/nve-navigation-card.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
layout: component
---

<CodeExamplePreview>

```html
<nve-navigation-card
href="#"
label="Om hydrologisk avdeling"
additionalText="Norges vassdrags- og energidirektorat er nasjonal faginstitusjon i hydrologi."
></nve-navigation-card>
<nve-navigation-card
href="#"
label="Fakta om vannets kretsløp"
iconPath="/assets/nve-illustrasjoner-ikon-vannkraft.png"
></nve-navigation-card>
```

</CodeExamplePreview>

## Eksempler

### Tittel

Tittel vises alltid øverst i kortet, og under ikon dersom ikon er lagt inn med `iconPath`. Tittelen er det viktigste innholdet og bør være kort og beskrivende.

<CodeExamplePreview>

```html
<nve-navigation-card href="#" label="Tittel" />
```

</CodeExamplePreview>

### Med tilleggstekst

Du kan legge til en ekstra tekst under hovedlenkens overskrift ved å bruke `additionalText`-egenskapen. Både overskriften og den tilhørende teksten blir lest opp av skjermlesere, så sørg for at teksten er kortfattet og lett å forstå.

<CodeExamplePreview>

```html
<nve-navigation-card
href="#"
label="Om hydrologisk avdeling"
additionalText="Norges vassdrags- og energidirektorat er nasjonal faginstitusjon i hydrologi."
/>
```

</CodeExamplePreview>

### Med lang tilleggstekst

Tilleggstekst vises maksimalt på 3 linjer. Dersom teksten er lengre, kuttes den av med `...`.

<CodeExamplePreview>

```html
<nve-navigation-card
href="#"
label="Vannkraft i Norge"
additionalText="Norge er verdens sjette største produsent av vannkraft, og nesten all norsk strømproduksjon kommer fra vannkraftverk. Vannkraften utnytter høydeforskjeller i elver og innsjøer til å produsere ren og fornybar energi. NVE forvalter Norges vannressurser og har ansvar for å regulere og overvåke kraftproduksjonen i landet."
/>
```

</CodeExamplePreview>

### Med ikon fra ikon-fil

Ikonsettet som skal brukes er de som hos NVE kalles [Illustrasjonsikoner](https://nve.frontify.com/d/n2ujvoktZ3dr/nve-profil#/ikoner-illustrasjoner/illustrasjonsikoner-1). Ikon skal **ikke** kombineres med ekstratekst (`additionalText`). Dersom både `additionalText` og `iconPath` er brukt, vil ikonet vises og `additionalText` skjules.

<CodeExamplePreview>

```html
<nve-navigation-card
href="#"
label="Fakta om vannets kretsløp"
iconPath="/assets/nve-illustrasjoner-ikon-vannkraft.png"
>
</nve-navigation-card>
<nve-navigation-card href="#" label="Fakta om flom og farer" iconPath="/assets/nve-illustrasjoner-ikon-flom.png">
</nve-navigation-card>
```

</CodeExamplePreview>

### Klikkhandlinger

Man kan velge mellom 3 klikk-handlinger ved bruk av `clickAction`-egenskapen. Handlingen bestemmer både funksjonaliteten og hvilket ikon som vises i kortet. Standardverdi er `internal`.

#### Intern

`internal` håndterer intern routing. Brukes når brukeren skal navigere innenfor samme applikasjon. Sett `href` for å definere URL-en.

<CodeExamplePreview>

```html
<nve-navigation-card
label="Intern"
additionalText="Klikk for å gå til intern linke"
clickAction="internal"
href="/components/nve-button.html"
>
</nve-navigation-card>
```

</CodeExamplePreview>

#### Ekstern

`external` åpner en ekstern side. Automatisk settes `target="_blank"` på `<a>`-elementet. Se anbefalinger for eksterne lenker i seksjonen [Tilgjengelighet](#tilgjengelighet).

<CodeExamplePreview>

```html
<nve-navigation-card label="Ekstern (åpnes i en ny fane)" clickAction="external" href="https://www.nve.no/">
</nve-navigation-card>
```

</CodeExamplePreview>

#### Nedlasting

`download` starter nedlasting av en fil. Legger til `download`-attributtet slik at nettleseren forstår at lenken ikke skal navigere videre. Dersom du ønsker spesifikk filhåndtering, kan du implementere det selv med en vanlig `onClick`-metode (avhengig av rammeverket du bruker).

<nve-message-card variant="warning" label="Viktig!" size="compact">
<p>Hvis filen ligger på en annen origin enn applikasjonen, vil lenken ikke laste ned filen, men i stedet åpne adressen fra <b>href</b>-attributtet. I slike tilfeller må du selv håndtere nedlastingen med onClick.</p>
</nve-message-card>

<CodeExamplePreview>

```html
<nve-navigation-card label="Last ned Mardalsfossen bilde (JPEG, 72 KB)" clickAction="download"> </nve-navigation-card>
```

</CodeExamplePreview>

## Bruk med klient-side routing i SPA-applikasjoner

Når man benytter klientside-routing, for eksempel med `routerLink` (Vue) eller `Link` (React), genereres et eget `<a>`-element av rammeverket.
I disse tilfellene blir `nve-navigation-card` pakket inn i en `<a>`. For å unngå ugyldig HTML-struktur med `<a>`-elementer inni hverandre, sjekker `nve-navigation-card` derfor om dets direkte forelder er et `<a>`. Hvis dette er tilfelle, rendres kortet som et `<div>` i stedet for et `<a>`.

På denne måten beholdes mest funksjonalitet og styling fra `nve-navigation-card`, samtidig som man unngår semantiske og tekniske problemer med nestede lenker.

**Eksempel i Vue:**

```vue
<RouterLink to="components/Komponentoversikt">
<nve-navigation-card
href="#"
label="Om hydrologisk avdeling"
additionalText="Tekst her skal ikke kombineres med ikon"
/>
</RouterLink>
```

**Eksempel i React:**

```jsx
<Link to="/components/Komponentoversikt">
<nve-navigation-card
href="#"
label="Om hydrologisk avdeling"
additionalText="Tekst her skal ikke kombineres med ikon"
/>
</Link>
```

## Retningslinjer

- **Bruk `nve-navigation-card`** for hovednavigasjon på oversikts- eller inngangssider der brukeren skal velge mellom flere hovedtemaer eller seksjoner.
- **Bruk [`nve-link-card`](/components/nve-link-card)** for sekundære lenker, handlinger, eller når du trenger støtte for eksterne lenker, nedlasting eller e-post.
- Ikke bruk `nve-navigation-card` for valg, ekspanderbare paneler eller andre interaktive kort – bruk dedikerte komponenter for dette.
- Komponentet har både minimum og maksimum høyde for konsistent layout.
- **Ikon skal ikke kombineres med ekstratekst** (`additionalText`). Hvis `ikonPath` er lagt inn, vises ikke tilleggstekst.
- **Kun illustrasjonsikoner skal brukes som ikon**. Disse finnes i [NVE Frontify – Illustrasjonsikoner](https://nve.frontify.com/d/n2ujvoktZ3dr/nve-profil#/ikoner-illustrasjoner/illustrasjonsikoner-1/nedlasting). Illustrasjonsikonene illustrerer NVEs virksomhetsområder og er detaljrike. De skal ikke brukes for å indikere navigasjon eller handling, og fungerer dårlig i små størrelser.
- Bruk alltid komponenten i et grid- eller flex-oppsett for å sikre riktig spacing og responsivitet.

## Tilgjengelighet

- **Tittel (`label`-feltet) rendres som `<h2>`** for å sikre god semantikk og tilgjengelighet. Dette gjør det enklere for brukere med skjermleser å navigere mellom hovedseksjoner på siden. Hvis du har flere navigation-cards på samme side, vil de automatisk utgjøre en oversiktlig seksjonsstruktur.
- Komponentet rendres som `<a>` hvis det ikke ligger inni en lenke, og som `<div>` hvis det pakkes inn i en `<a>` (for å unngå nestede lenker).
- Ikon og tilleggstekst skal **ikke** vises samtidig.
- Ekstratekst trunkeres automatisk etter 3 linjer for å sikre at kortet ikke blir for høyt og at innholdet er lett å skanne.
- Understrek (text-decoration) på wrapper-`<a>` fjernes av designsystemet ved hjelp av en regel i `global.css` (`a:has(nve-navigation-card) { text-decoration: unset; }`). Dette sikrer at det ikke vises uønsket understrek på lenker som wrapper `nve-navigation-card`, siden webkomponenter bruker Shadow DOM og ikke kan påvirke wrapperens styling direkte.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions public/css/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ a {
color: var(--color-neutrals-foreground-primary, #0d0d0e);
}

/* Brukes for å fjerne standard linje i <a> som ikke er i Shadow-DOMen som f.eks de som skal wrappe <nve-link-card> */
a:has(nve-link-card) {
/* Brukes for å fjerne standard linje i <a> som ikke er i Shadow-DOMen som f.eks de som skal wrappe <nve-link-card> og <nve-navigation-card> */
a:has(nve-link-card),
a:has(nve-navigation-card) {
text-decoration: unset;
}

Expand Down
2 changes: 2 additions & 0 deletions src/components/nve-icon/offline-icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
* velg aktuelt ikon, velg 24px størrelse og svart farge og "copy icon to clipboard"
*/
export const offlineIcons: { [key: string]: string } = {
arrow_forward: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M647-440H160v-80h487L423-744l57-56 320 320-320 320-57-56 224-224Z"/></svg>`,
check_circle:
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#000000"><path d="m424-296 282-282-56-56-226 226-114-114-56 56 170 170Zm56 216q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>',
chevron_backward: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#000000"><path d="M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z"/></svg>`,
chevron_forward: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#000000"><path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>`,
close: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#000000"><path d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"/></svg>`,
download: `<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#000000"><path d="M480-320 280-520l56-58 104 104v-326h80v326l104-104 56 58-200 200ZM160-160v-200h80v120h480v-120h80v200H160Z"/></svg>`,
error: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#000000"><path d="M480-280q17 0 28.5-11.5T520-320q0-17-11.5-28.5T480-360q-17 0-28.5 11.5T440-320q0 17 11.5 28.5T480-280Zm-40-160h80v-240h-80v240Zm40 360q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>`,
info: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#000000"><path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>`,
lock: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#000000"><path d="M240-80q-33 0-56.5-23.5T160-160v-400q0-33 23.5-56.5T240-640h40v-80q0-83 58.5-141.5T480-920q83 0 141.5 58.5T680-720v80h40q33 0 56.5 23.5T800-560v400q0 33-23.5 56.5T720-80H240Zm0-80h480v-400H240v400Zm240-120q33 0 56.5-23.5T560-360q0-33-23.5-56.5T480-440q-33 0-56.5 23.5T400-360q0 33 23.5 56.5T480-280ZM360-640h240v-80q0-50-35-85t-85-35q-50 0-85 35t-35 85v80ZM240-160v-400 400Z"/></svg>`,
Expand Down
Loading
Loading