Gå til innholdet

Drupal SDC

Denne guiden viser hvordan du tar i bruk Artsdatabanken Web Components i et Drupal-tema ved hjelp av Single Directory Components (SDC), introdusert i Drupal 10.1.


To lag — ikke ett

SDC og Web Component er to forskjellige ting som jobber sammen:

LagHva det erBrukes av
<adb-button> (Web Component)Selve komponenten — atferd, styling, shadow DOMAlle konsumenter: Drupal, Angular, React, m.m.
SDC button/En Drupal-adapter — pakker WC inn i Drupals komponentsystemDrupal-utviklere / temabyggere

SDC erstatter ikke Web Componenten — den er et tynt Drupal-skall rundt den.

npm-pakke (@artsdatabanken/components) ← kilde til sannhet, deles overalt
Drupal-bibliotek (libraries.yml) ← laster inn JS som type="module"
SDC-komponent (button/) ← Drupal-vennlig API (props → WC-attributter)
Twig-maler ← brukes via {% include 'artsdatabanken:button' %}

Den største fordelen med å gå via SDC fremfor å skrive <adb-button> direkte i en Twig-mal:

  • Prop-valideringbutton.component.yml håndhever tillatte verdier (enum), slik at feil oppdages tidlig
  • PHP render arrays — backend-moduler kan rendre knapper uten å berøre Twig
  • Sentralisert attributt-mapping — hvis en WC-attributt omdøpes, er det bare SDC-malen som må oppdateres
  • Automatisk biblioteksinnlastinglibraryOverrides sørger for at JS lastes inn hver gang komponenten inkluderes

Filstruktur

web/themes/custom/artsdatabanken/
├── artsdatabanken.libraries.yml
└── components/
└── button/
├── button.component.yml ← SDC-definisjon (props, slots)
├── button.twig ← rendrer <adb-button>
└── button.css ← valgfritt: token-overstyringer

Steg 1 — Last inn Web Componenten

Alternativ A: Vite-entry (anbefalt for artsdatabanken.no)

Siden artsdatabanken.no bruker Vite, er det enkleste å importere komponentene i temaets TypeScript-entry. Vite tree-shaker og bundler kun det du faktisk importerer.

themes/custom/artsdatabanken/src/index.ts
import '@artsdatabanken/components/dist/adb-button.js';

Registrer Vite-outputfilen som et Drupal-bibliotek i stedet for å peke direkte til node_modules.

Alternativ B: libraries.yml

artsdatabanken.libraries.yml
adb-components:
js:
/themes/custom/artsdatabanken/node_modules/@artsdatabanken/components/dist/index.js:
attributes:
type: module
dependencies:
- core/drupal

Steg 2 — Definer SDC-komponenten

button.component.yml

name: Button
description: Artsdatabanken-knapp — pakker inn adb-button Web Component.
props:
type: object
properties:
variant:
type: string
title: Variant
default: primary
enum: [primary, secondary, ghost]
size:
type: string
title: Størrelse
default: md
enum: [sm, md, lg]
disabled:
type: boolean
title: Deaktivert
default: false
slots:
label:
title: Etikett
libraryOverrides:
dependencies:
- artsdatabanken/adb-components

Steg 3 — Skriv Twig-malen

button.twig

<adb-button
variant="{{ variant|default('primary') }}"
size="{{ size|default('md') }}"
{{ disabled ? 'disabled' : '' }}
>
{% block label %}{{ label }}{% endblock %}
</adb-button>

Steg 4 — Bruk komponenten

Fra en Twig-mal:

{% include 'artsdatabanken:button' with {
variant: 'primary',
size: 'md',
label: 'Lagre'|t
} %}

Fra PHP (render array):

$build['save_button'] = [
'#type' => 'component',
'#component' => 'artsdatabanken:button',
'#props' => [
'variant' => 'primary',
'size' => 'md',
],
'#slots' => [
'label' => ['#markup' => $this->t('Lagre')],
],
];

FOUC — Flash of Unstyled Content

Web Components oppgraderes klient-side etter at JS er lastet. Inntil da kan nettleseren vise ustilt markup. Bruk en lagdelt tilnærming:

Lag 1 — Basisskjuling (alle komponenter)

Legg til i temaets globale CSS:

adb-button:not(:defined),
adb-card:not(:defined),
adb-input:not(:defined) {
visibility: hidden;
}

Skjuler udefinerte elementer til de er oppgradert. Enkel løsning, ingen ekstra infrastruktur.

Lag 2 — Kritiske komponenter over folden: Declarative Shadow DOM

For høyt synlige komponenter over folden kan du bygge inn shadow root direkte i server-rendret HTML, slik at nettleseren kan male den før JS lastes:

{# button.twig — DSD-variant for kritisk bruk over folden #}
<adb-button variant="{{ variant }}" size="{{ size }}" {{ disabled ? 'disabled' : '' }}>
<template shadowrootmode="open">
<style>
:host { display: inline-block; }
:host([disabled]) { opacity: 0.5; pointer-events: none; }
button {
background: var(--adb-color-primary, #2d6a4f);
color: var(--adb-color-primary-text, #fff);
border: 2px solid var(--adb-color-primary, #2d6a4f);
border-radius: var(--adb-radius, 0.375rem);
padding: 0.5rem 0.75rem;
font-family: inherit;
cursor: pointer;
}
</style>
<button part="base"><slot></slot></button>
</template>
{{ label }}
</adb-button>

NB: Denne tilnærmingen dupliserer komponent-CSS i Twig. Bruk den kun for et lite antall kritiske komponenter (hero-CTAer, handlingsknapper over folden). Når JS lastes, overtar Lit uten visuell endring.

Lag 3 — Innholdskomponenter: meningsfulle light DOM-slots

For innholdsrike komponenter (kort, artikler) — plasser meningsfullt innhold i light DOM-slots. Det er alltid synlig for brukere og søkemotorer, uavhengig av JS:

<adb-card>
<h3 slot="title">{{ title }}</h3>
<p slot="description">{{ description }}</p>
<img slot="image" src="{{ image_url }}" alt="{{ image_alt }}">
</adb-card>

Sjekkliste for ny komponent i Drupal

  • Komponenten er bygget og eksportert fra @artsdatabanken/components
  • Komponenten er importert i Vite-entry (eller lagt til i libraries.yml)
  • SDC component.yml er skrevet med riktige props og slots
  • Twig-mal rendrer custom element med mappede attributter
  • :not(:defined)-regel er lagt til i global tema-CSS
  • DSD-mal skrevet for eventuell bruk over folden