Esikatselu
function ExamplePanel() {
const [isOpen, setIsOpen] = useState(false);
return (
<Panel heading="Lorem ipsum" isOpen={isOpen} onClick={() => setIsOpen(!isOpen)}>
<PanelBody>Dolor sit amet</PanelBody>
</Panel>
);
}
Käyttötarkoitus
Paneeli on tarkoitettu saman aihealueen sisältöjen ryhmittelyyn selkeiksi asiakokonaisuuksiksi. Esimerkiksi lomakkeet sisäisissä järjestelmissä.
- Ryhmittele paneeliin samaan asiakokonaisuuteen liittyviä elementtejä.
- Asemoi paneelin painikkeet pääsääntöisesti oikeaan alareunaan.
- Älä aseta paneeleita sisäkkäin.
- Älä käytä paneelia ryhmittelemään listoja (esim. hakutulokset) tai muuta staattista sisältöä kuten kuvia ja tekstiä.
- Älä käytä paneelia nostoelementtinä.
Saavutettavuus
Komponentti tuottaa oletuksena fieldset
-tagilla toteutetun lomakeryhmän, joka on otsikoitu paneelin otsikon
lisäksi visuaalisesti piilotetulla legend
-otsikolla.
Komponentti lisää avattavalle/suljettavalle paneelille automaattisesti ruudunlukijoille tarvittavat ARIA-attribuutit.
Jos paneelia käytetään asioiden ryhmittelyyn ilman lomaketoiminnallisuuksia tai lomakkeen ryhmittely rakennetaan paneelin sisään,
paneeli muutetaan as
-propilla esimerkiksi section
-elementiksi (as="section"
). Tämä poistaa legend
-elementin automaattisesti käytöstä.
Myös paneelin ollessa fieldset
, voi legend
-elementin poistaa käytöstä legend
-propilla. Tällöin tulee huolehtia kuitenkin ryhmän nimeämisestä.
Rakenne
Paneeli koostuu useammasta komponentista:
Panel
- Paneeli
PanelBody
- Paneelin sisennetty sisältöalue, esim. lomake-elementeille
PanelActions
- Paneeliin liittyvät toimintopainikkeet
Esimerkit
Avattava paneeli
Paneelista saa tehtyä avattavan/suljettavan lisäämällä Panel
-komponentille isOpen
- ja onClick
-propit.
Tilan hallinta tapahtuu komponentin ulkopuolella.
function ExamplePanel() {
const [isOpen, setIsOpen] = useState(false);
return (
<Panel
as="section"
aria-labelledby="example-panel-heading"
heading="Primary"
headingId="example-panel-heading"
isOpen={isOpen}
onClick={() => setIsOpen(!isOpen)}
variant="primary"
>
<PanelBody>PanelBody</PanelBody>
</Panel>
);
}
Lomake ja ilmoitus
Esimerkki paneelista, jonka sisälle on ryhmitelty samaan aiheeseen liittyviä lomakekenttiä.
Paneelin sisällä olevat ilmoitukset tasataan oletuksena paneelin reunoihin. Ilmoitukset sijoitetaan PanelBody
-komponentin ulkopuolelle.
function ExamplePanel() {
const [isOpen, setIsOpen] = useState(true);
return (
<form noValidate autoComplete="off">
<Panel heading="Käsittelyn aloitus" variant="primary" isOpen={isOpen} onClick={() => setIsOpen(!isOpen)}>
<Alert variant="danger" flush className="kds-mb-0">
<Text>
<strong>Tallennus epäonnistui.</strong> Pakollinen tieto puuttuu.
</Text>
</Alert>
<PanelBody>
<InputGroup>
<TextInput
select
labelText="Saapumiskanava"
leftCol={(children) => <Column xl={3}>{children}</Column>}
inputWidth={(children) => <Column xl={5}>{children}</Column>}
>
<option>Lorem</option>
<option>Ipsum</option>
<option>Dolor</option>
</TextInput>
</InputGroup>
<InputGroup>
<DatePickerV2
labelText="Vireilletulopäivä"
defaultValue="2020-10-30"
leftCol={(children) => <Column xl={3}>{children}</Column>}
inputWidth={(children) => <Column xl={5}>{children}</Column>}
/>
</InputGroup>
<InputGroup>
<TextInput
select
labelText="Käsittelyn tyyppi"
leftCol={(children) => <Column xl={3}>{children}</Column>}
inputWidth={(children) => <Column xl={5}>{children}</Column>}
>
<option>Lorem</option>
<option>Ipsum</option>
<option>Dolor</option>
</TextInput>
</InputGroup>
<InputGroup>
<DateRangePickerV2
labelText="Haettu aika"
leftCol={(children) => <Column xl={3}>{children}</Column>}
invalid={{ from: true, to: true }}
errorText="Haettu aika puuttuu. Syötä alkamis- ja päättymispäivämäärä."
/>
</InputGroup>
<InputGroup row className="kds-mb-0">
<Column xl={3} />
<Column>
<Checkbox labelText="Kiireellinen käsittely" />
</Column>
</InputGroup>
</PanelBody>
<PanelActions>
<ButtonGroup horizontal="sm">
<Button>Tallenna</Button>
<Button appearance="outline">Peruuta</Button>
</ButtonGroup>
</PanelActions>
</Panel>
</form>
);
}
Taulukko ja haitarielementti
Taulukot ja haitarielementit tulee tasata oletuksena paneelin reunoihin asettamalla ne PanelBody
-komponentin ulkopuolelle.
Lisäksi Table
-komponentille annetaan kds-table--panel
apuluokka, joka muuttaa taulukon marginaalit vastaamaan paneelia.
<form noValidate autoComplete="off">
<Panel heading="Asumistiedot" variant="primary">
<Table className="kds-m-0 kds-table--panel">
<TableHead>
<TableRow>
<TableHeader>Osoite</TableHeader>
<TableHeader>Asumisaika</TableHeader>
<TableHeader>Asumismuoto</TableHeader>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>Puumökki, Röllimetsä</TableCell>
<TableCell>1.1.1986-</TableCell>
<TableCell>Omistusasunto</TableCell>
</TableRow>
<TableRow>
<TableCell>Pikku Kakkosen posti, PL 347, 33101 Tampere</TableCell>
<TableCell>1.11.1977-</TableCell>
<TableCell>Omistusasunto</TableCell>
</TableRow>
<TableRow>
<TableCell>Kneippbyn 11, 622 61 Visby, Ruotsi</TableCell>
<TableCell>1.1.1970-</TableCell>
<TableCell>Omistusasunto</TableCell>
</TableRow>
</TableBody>
</Table>
<PanelBody>
<Checkbox id="asumistieto-ei-tarvetta" labelText="Asumistietoja ei ole tarvetta antaa" />
</PanelBody>
<PanelActions>
<Button appearance="outline">Lisää asunto</Button>
</PanelActions>
</Panel>
</form>
Paneeli haitarielementeillä
Haitarielementtiä voi käyttää ryhmittelyyn paneelin sisällä. Vältä kuitenkin sisäkkäisiä haitarielementtejä.
function ExamplePanel() {
const { isToggleOn, flipToggle } = useToggle();
return (
<Panel
aria-labelledby="example-panel-accordion-heading"
as="section"
className="kds-mb-0"
heading="Poikkeuksellinen käsittely"
headingId="example-panel-accordion-heading"
variant="primary"
>
<Accordion id="panel-accordion-1" isOpen={isToggleOn("panel-accordion-1")}>
<AccordionToggle onClick={() => flipToggle("panel-accordion-1")}>
Lokitiedot mahdollistavat valvonnan
</AccordionToggle>
<AccordionBody>
Terveydenhuollon ammattilainen saa katsella ja käyttää potilastietoja ainoastaan silloin, kun tietoja
tarvitaan asiakkaan hoitamiseen. Terveydenhuolto hallinnoi, kenellä on oikeudet potilastietojen käsittelyyn
tietojärjestelmissä. Tietoja käsittelevien ammattilaisten tulee tunnistautua terveydenhuollon
ammattikorteilla.
</AccordionBody>
</Accordion>
<Accordion id="panel-accordion-2" isOpen={isToggleOn("panel-accordion-2")}>
<AccordionToggle onClick={() => flipToggle("panel-accordion-2")}>
<span className="kds-flex kds-justify-between kds-items-center">
<span>Rekisterinpitäjä vastaa tietojen oikeellisuudesta</span>
<Badge variant="primary">Ei annettu</Badge>
</span>
</AccordionToggle>
<AccordionBody>
Potilastietojen rekisterinpitäjä on se terveydenhuollon palvelunantaja, joka tiedot on tuottanut ja
tallentanut Potilastiedon arkistoon. Rekisterinpitäjä on vastuussa tuottamiensa potilastietojen
oikeellisuudesta ja virheellisten tietojen korjaamisesta.
</AccordionBody>
</Accordion>
<Accordion id="panel-accordion3" isOpen={isToggleOn("panel-accordion3")}>
<AccordionToggle onClick={() => flipToggle("panel-accordion3")}>
<span className="kds-flex kds-justify-between kds-items-center">
<span>Tietojen luovuttaminen</span>
<Badge variant="primary">Ei annettu</Badge>
</span>
</AccordionToggle>
<AccordionBody>
Potilastiedon arkistoon tallennetut potilastiedot ovat aina tiedot tallentaneen rekisterinpitäjän
käytettävissä. Jos potilastietoja haetaan toisen terveydenhuollon rekisterinpitäjän rekisteristä, kyseessä on
tietojen luovuttaminen, johon tarvitaan asiakkaan luovutuslupa.
</AccordionBody>
</Accordion>
</Panel>
);
}
Skeleton
Esimerkki Skeleton-komponentin soveltamisesta paneelissa.
Skeleton räätälöidään vastaamaan paneelin karkeaa rakennetta. Skeletonin kanssa käytetään variant="light"
-vaihtoehtoa.
<Panel as="div" variant="light" heading={<Skeleton className="kds-block kds-w-2/4 kds-mb-4" />}>
<PanelBody>
<InputGroup row className="kds-items-center">
<Column xl={3}>
<Skeleton variant="text" className="kds-block kds-w-3/4" />
</Column>
<Column xl={5}>
<Skeleton className="kds-p-2" />
</Column>
</InputGroup>
<InputGroup row className="kds-items-center">
<Column xl={3}>
<Skeleton variant="text" className="kds-block kds-w-3/4" />
</Column>
<Column xl={5}>
<Skeleton className="kds-p-2" />
</Column>
</InputGroup>
<InputGroup row className="kds-items-center kds-mb-0">
<Column xl={3}>
<Skeleton variant="text" className="kds-block kds-w-3/4" />
</Column>
<Column xl={5}>
<Skeleton className="kds-p-2" />
</Column>
</InputGroup>
</PanelBody>
<PanelActions>
<Skeleton className="kds-p-2 kds-w-24" />
</PanelActions>
</Panel>