Skip to content

Støtte for SSR av Tabs med riktig default value #5001

@IbenLindDragesund

Description

@IbenLindDragesund

Versjon

1.15.0

Beskrivelse

NTNU bruker Designsystemet i et Next.js-prosjekt, og har oppdaget at Tabs-komponenten ikke får riktig default value ved SSR. Ved bruk av i et oppstår det et synlig blink, hvor siden lastes med første tab valgt, og deretter hopper den til riktig (default) tab. Vi oppdaget dette da vi valgte å hente og sette defaultValue fra et URL-parameter. Her er et eksempel med parameter ?tab=exam, så kan man se hvordan siden blinker når den lastes på nytt.

Tab-default-value-bug.mp4

Additional Information

Antatt årsak

TabsTab-komponenten rendrer ikke aria-selected som et deklarativt attributt. SSR-outputen inneholder derfor ingen tab med aria-selected="true". Når u-tabs (det underliggende web component-biblioteket) kobles til DOM-en via connectedCallback, finner den ingen valgt tab og auto-velger automatisk første tab. Deretter kjører useEffect i Tabs-komponenten og setter aria-selected på riktig tab. Dette gir altså et synlig hopp på grunn av skiftet.

Foreslått løsning

Rendre aria-selected deklarativt i TabsTab basert på context:

<ds-tab
  aria-selected={currentValue === value ? 'true' : undefined}
  ...
/>

Dette vil muligens også gjøre begge disse useEffect-ene overflødige (tabs.tsx - linje: 83-98):

useEffect(() => {
  if (!isControlled || !tabsRef.current || value === undefined) return;
  tabsRef.current?.tabList?.tabs?.forEach((tab) => {
    if (tab.getAttribute('data-value') === value)
      tab.setAttribute('aria-selected', 'true');
  });
}, [value, isControlled]);

useEffect(() => {
  if (defaultValue && tabsRef.current) {
    tabsRef.current?.tabList?.tabs?.forEach((tab) => {
      if (tab.getAttribute('data-value') === defaultValue)
        tab.setAttribute('aria-selected', 'true');
    });
  }
}, []);

Vi har ikke testet fiksen selv, men håper at tilbakemeldingen og forslaget kan være nyttig likevel.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    📥 Inbox

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions