Skip to content

Commit

Permalink
Pilnavigering (#116)
Browse files Browse the repository at this point in the history
* implementer pilnavigering med intern state

når bruker velger med space, enter eller click så oppdateres valgtOrganisassjon
intern state i menyen resettes ved lukk
oppdatert tsconfig lang level for å kunne bruke flatMap.

* oppdater versjon

* set release versjon

* set esnext
  • Loading branch information
kenglxn authored Feb 16, 2023
1 parent 3815896 commit 08febe6
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 22 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@navikt/bedriftsmeny",
"version": "6.3.0",
"version": "6.4.0",
"description": "Bedriftsvelger og -meny for innlogget arbeidsgiver. Laget av TAG (Tjenester for Arbeidsgivere).",
"author": "NAVIKT",
"license": "MIT",
Expand Down
18 changes: 9 additions & 9 deletions src/bedriftsmeny/velger/JuridiskEnhet.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {forwardRef, FunctionComponent, Ref} from 'react';
import { Office1, Success } from '@navikt/ds-icons';
import { Accordion, BodyShort, Button } from '@navikt/ds-react';
import { JuridiskEnhetMedUnderEnheterArray, Organisasjon } from '../organisasjon';
import React, {forwardRef, useState} from 'react';
import {Office1, Success} from '@navikt/ds-icons';
import {Accordion, BodyShort, Button} from '@navikt/ds-react';
import {JuridiskEnhetMedUnderEnheterArray, Organisasjon} from '../organisasjon';

type Props = {
juridiskEnhet: JuridiskEnhetMedUnderEnheterArray;
Expand All @@ -19,14 +19,14 @@ const JuridiskEnhet = forwardRef<HTMLButtonElement, Props>(({
const juridiskEnhetErValgt = Underenheter.some(
(enhet: Organisasjon) => enhet.OrganizationNumber === valgtOrganisasjon.OrganizationNumber
);
const [open, setOpen] = useState(juridiskEnhetErValgt)

return (
<li className="navbm-virksomhetsvelger__juridisk-enhet">
<Accordion.Item
key={JuridiskEnhet.OrganizationNumber}
defaultOpen={juridiskEnhetErValgt}
>
<Accordion.Header className="navbm-virksomhetsvelger__enhet navbm-virksomhetsvelger__enhet--juridisk">
<Accordion.Item open={open}>
<Accordion.Header
className="navbm-virksomhetsvelger__enhet navbm-virksomhetsvelger__enhet--juridisk"
onClick={() => { setOpen(!open); }}>
<div className="navbm-virksomhetsvelger__enhet-tekst">
<BodyShort className="navbm-virksomhetsvelger__enhet-tittel">
{JuridiskEnhet.Name}
Expand Down
106 changes: 97 additions & 9 deletions src/bedriftsmeny/velger/Virksomhetsvelger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,32 @@ import {VirksomhetsvelgerContext} from './VirksomhetsvelgerProvider';
import JuridiskEnhet from './JuridiskEnhet';
import Dropdown from "./Dropdown";

export const useKeyboardEvent = (type: 'keydown' | 'keypress' | 'keyup', containerRef: React.RefObject<HTMLElement>, handler: (event: KeyboardEvent) => void) => {
React.useEffect(() => {
const listener = (event: KeyboardEvent) => {
const node = containerRef.current
if (node === null) {
return
}

if (node !== event.target && !node.contains(event.target as HTMLElement)) {
return
}

handler(event);
};
document.addEventListener(type, listener);
return () => {
document.removeEventListener(type, listener);
};
}, [type, containerRef, handler]);
}

const Velger = () => {
const buttonRef = useRef<HTMLButtonElement>(null);
const lukkKnappRef = useRef<HTMLButtonElement>(null);
const søkefeltRef = useRef<HTMLInputElement>(null);
const listeRef = useRef<HTMLUListElement>(null);
const valgtUnderenhetRef = useRef<HTMLButtonElement>(null);
const dropdownRef = useRef<HTMLDivElement>(null);
const [åpen, setÅpen] = useState<boolean>(false);
Expand All @@ -19,6 +43,50 @@ const Velger = () => {
søketekst,
setSøketekst,
} = useContext(VirksomhetsvelgerContext);
const [valgtUnderenhetIntern, velgOrganisasjonIntern] = useState(valgtOrganisasjon)
const underenheterFlat = aktivtOrganisasjonstre.flatMap(({Underenheter }) => [...Underenheter]);
const antallTreff = underenheterFlat.length;

useKeyboardEvent('keydown', listeRef, (e) => {
if (e.key === 'Enter') {
valgtUnderenhetRef.current?.click()
e.preventDefault()
}

if (e.key === 'Tab') {
if (e.shiftKey) {
lukkKnappRef.current?.focus()
} else {
søkefeltRef.current?.focus()
}
e.preventDefault()
}

if (e.key === 'Home') {
velgOrganisasjonIntern(underenheterFlat[0])
e.preventDefault()
}

if (e.key === 'End') {
velgOrganisasjonIntern(underenheterFlat[underenheterFlat.length - 1])
e.preventDefault()
}

if (e.key === 'ArrowUp' || e.key === 'Up') {
const index = underenheterFlat.findIndex(({OrganizationNumber}) => OrganizationNumber === valgtUnderenhetIntern.OrganizationNumber)
const nextIndex = Math.max(0, index - 1)
velgOrganisasjonIntern(underenheterFlat[nextIndex])
e.preventDefault()
}

if (e.key === 'ArrowDown' || e.key === 'Down') {
const index = underenheterFlat.findIndex(({OrganizationNumber}) => OrganizationNumber === valgtUnderenhetIntern.OrganizationNumber)
const nextIndex = Math.min(underenheterFlat.length - 1, index + 1)
velgOrganisasjonIntern(underenheterFlat[nextIndex])
e.preventDefault()
}

});

const toggleVelger = (verdi?: boolean) => {
setÅpen(verdi === undefined ? !åpen : verdi);
Expand All @@ -32,14 +100,11 @@ const Velger = () => {
useEffect(() => {
if (åpen) {
valgtUnderenhetRef.current?.focus();
} else {
setSøketekst('')
velgOrganisasjonIntern(valgtOrganisasjon)
}
}, [åpen]);

const antallTreff = aktivtOrganisasjonstre.reduce(
(totaltAntall, juridiskEnhet) => totaltAntall + juridiskEnhet.Underenheter.length,
0
);

}, [åpen, valgtUnderenhetIntern]);

const handleClickOutside: { (event: MouseEvent | KeyboardEvent): void } = (
e: MouseEvent | KeyboardEvent
Expand Down Expand Up @@ -107,17 +172,39 @@ const Velger = () => {
>
<div className="navbm-virksomhetsvelger__popup-header">
<Search
ref={søkefeltRef}
variant="simple"
value={søketekst}
onChange={setSøketekst}
placeholder="Søk på virksomhet ..."
label="Søk på virksomhet"
onKeyDown={(e) => {
if (e.key === 'Tab' && e.shiftKey) {
if (underenheterFlat.some(({OrganizationNumber}) => OrganizationNumber === valgtUnderenhetIntern.OrganizationNumber)) {
valgtUnderenhetRef.current?.focus()
} else {
velgOrganisasjonIntern(underenheterFlat[0])
}
e.preventDefault()
}
}}
/>
<Button
ref={lukkKnappRef}
variant="tertiary"
aria-label="lukk"
className="navbm-virksomhetsvelger__popup-header-xbtn"
onClick={() => setÅpen(false)}
onKeyDown={(e) => {
if (e.key === 'Tab' && !e.shiftKey) {
if (underenheterFlat.some(({OrganizationNumber}) => OrganizationNumber === valgtUnderenhetIntern.OrganizationNumber)) {
valgtUnderenhetRef.current?.focus()
} else {
velgOrganisasjonIntern(underenheterFlat[0])
}
e.preventDefault()
}
}}
>
<Close aria-hidden={true}/>
</Button>
Expand All @@ -130,13 +217,14 @@ const Velger = () => {
<Accordion style={{display: "flex", overflow: "auto"}}>
<ul
className="navbm-virksomhetsvelger__juridiske-enheter"
ref={listeRef}
>
{aktivtOrganisasjonstre.map((juridiskEnhet) => (
<JuridiskEnhet
ref={valgtUnderenhetRef}
key={juridiskEnhet.JuridiskEnhet.OrganizationNumber}
key={juridiskEnhet.JuridiskEnhet.OrganizationNumber + valgtUnderenhetIntern.OrganizationNumber}
juridiskEnhet={juridiskEnhet}
valgtOrganisasjon={valgtOrganisasjon}
valgtOrganisasjon={valgtUnderenhetIntern}
onUnderenhetClick={onUnderenhetClick}
/>
))}
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"allowJs": true,
"target": "es2016",
"target": "esnext",
"esModuleInterop": true
},
"include": ["src/**/*", "index.tsx"]
Expand Down

0 comments on commit 08febe6

Please sign in to comment.