OTTODesign System

Components

Link

Links serve as navigational elements that assist users to move within a page, to a different page on the same website, or to external websites and resources.

Configurator

LiveLink: inverted variants belong on dark grounds, switch the scheme to Dark to try them.
HTML
<oc-link-v2><a href="#">Alle Angebote</a></oc-link-v2>

Usage

Variants

These are the following variants of a Link:

  • Primary Links are used for the most important links on a page or for inline links.
  • Secondary Links are intended for less important links on a page. Be careful when using them as they have a lower click affordance compared to primary links.
  • Sale Links are used for content that is used in the context of a sale, for example, 'Sale' categories in the navigation menu.
  • Underlined Links are only placed on light colored backgrounds. They come in regular and bold.
  • Inverted Links are only placed on dark backgrounds. They come in regular and bold.

underlined

Alle Angebote

underlined-bold

Alle Angebote
Liveprimary, secondary, underlined regular, and underlined bold links
HTML
<p class="demo-label">primary</p><oc-link-v2><a href="#">Alle Angebote</a></oc-link-v2></div>
<p class="demo-label">secondary</p><oc-link-v2 variant="secondary"><a href="#">Hilfe &amp; Kontakt</a></oc-link-v2></div>
<p class="demo-label">sale</p><oc-link-v2 variant="sale"><a href="#">Zum Sale</a></oc-link-v2></div>
<p class="demo-label">underlined</p><oc-link-v2 variant="underlined"><a href="#">Alle Angebote</a></oc-link-v2></div>
<p class="demo-label">underlined-bold</p><oc-link-v2 variant="underlined-bold"><a href="#">Alle Angebote</a></oc-link-v2></div>

inverted-bold

Alle Angebote
Liveinverted and inverted bold
HTML
<p class="demo-label" style="color:#fff">inverted</p><oc-link-v2 variant="inverted"><a href="#">Alle Angebote</a></oc-link-v2></div>
<p class="demo-label" style="color:#fff">inverted-bold</p><oc-link-v2 variant="inverted-bold"><a href="#">Alle Angebote</a></oc-link-v2></div>

For standalone links, a larger link size may be used, while smaller sizes may be suitable for less important navigation elements.

Links are available in the following sizes:

Livelink 125, link 100, link 75 and link 50
HTML
<oc-link-v2 size="125"><a href="#">Alle Angebote</a></oc-link-v2>
<oc-link-v2 size="100"><a href="#">Alle Angebote</a></oc-link-v2>
<oc-link-v2 size="75"><a href="#">Alle Angebote</a></oc-link-v2>
<oc-link-v2 size="50"><a href="#">Alle Angebote</a></oc-link-v2>

You can also add an Icon to the left or right of the Link. Icons are optional and can be placed on either side of the Link. They visually communicate the Link's target and enhance user attention. Left-side Icons help reduce cognitive load by symbolizing the Link's action. Icons on the right are used as affordance for the interaction; for example, a leaving-page denotes an external target.

Link 100 and link 125 use icons in size 100, while link 75 and link 50 use icons in size 50.

Icon right

Zum Hersteller
Liveicon left and right
HTML
<p class="demo-label">Icon right</p><oc-link-v2 size="125" icon-right="leaving-page"><a href="#" target="_blank" rel="noopener">Zum Hersteller</a></oc-link-v2></div>
<p class="demo-label">Icon left</p><oc-link-v2 icon-left="smiley-positive"><a href="#">Bewertung schreiben</a></oc-link-v2></div>

Behavior

States

Hover, press and tab through the links to see their states

LiveStates
HTML
<oc-link-v2><a href="#">Alle Angebote</a></oc-link-v2></div>
<oc-link-v2 variant="secondary"><a href="#">Alle Angebote</a></oc-link-v2></div>
<oc-link-v2 variant="sale"><a href="#">Zum Sale</a></oc-link-v2></div>
<oc-link-v2 variant="underlined"><a href="#">Alle Angebote</a></oc-link-v2></div>
<oc-link-v2 variant="underlined-bold"><a href="#">Alle Angebote</a></oc-link-v2></div>
<oc-link-v2 variant="inverted"><a href="#">Alle Angebote</a></oc-link-v2></div>
<oc-link-v2 variant="inverted-bold"><a href="#">Alle Angebote</a></oc-link-v2></div>

Fitting

The width of links fits the content.

Livefit-content
HTML
<span style="background:rgba(229,0,107,.08);outline:1px dashed #e5006b"><oc-link-v2 size="125"><a href="#">Alles zu Lieferung und Versand</a></oc-link-v2></span>

Placement

Links can be placed in two ways: as stand-alone elements or inline within the surrounding text.

When inserting a link around continuous text, use the inline variant. This will underline the link, meeting WCAG Success Criterion 1.4.1 Use of Color. When using inline links, it is important to match the size of the link with the surrounding text. The technical size "inherit" may be used for that case.

Inline

Du kannst deine Bestellung kostenlos zurücksenden, innerhalb von 30 Tagen.

Livestand-alone and inline link
HTML
<p class="demo-label">Standalone</p>
<oc-link-v2 size="125"><a href="#">Rücksendung anmelden</a></oc-link-v2>
<p class="demo-label">Inline</p>
<p class="oc-copy-125">Du kannst deine Bestellung <oc-link-v2 size="inherit"><a href="#">kostenlos zurücksenden</a></oc-link-v2>, innerhalb von 30 Tagen.</p>

If you are placing multiple standalone links next to each other, make sure there is a 16px horizontal and 8px vertical gap between them.

Livehorizontal and vertical placing
HTML
<oc-link-v2 size="125"><a href="#">Damenmode</a></oc-link-v2><oc-link-v2 size="125"><a href="#">Herrenmode</a></oc-link-v2><oc-link-v2 size="125"><a href="#">Kindermode</a></oc-link-v2></div>
<oc-link-v2 size="125"><a href="#">Sneaker</a></oc-link-v2><oc-link-v2 size="125"><a href="#">Taschen</a></oc-link-v2><oc-link-v2 size="125"><a href="#">Schmuck</a></oc-link-v2></div>

Target

Links can have different targets. The three main types of link targets are:

  • Anchor Links direct users to a different section of the current page.
  • Internal Links navigate to a new page within the same website.
  • External Links direct users to an external website or file

Link: navigates

Zum Hersteller

Buttons: trigger actions

Zurück Weiter
Livelink vs. button
HTML
<p class="demo-label">Link: navigates</p>
<oc-link-v2 size="125" icon-right="leaving-page"><a href="#" target="_blank" rel="noopener">Zum Hersteller</a></oc-link-v2>
<p class="demo-label">Buttons: trigger actions</p>
<oc-button-v1 variant="secondary">Zurück</oc-button-v1>
<oc-button-v1 variant="primary">Weiter</oc-button-v1>

A link directs the user away from their current journey for exploration or additional information. Links can be used to move within a page, to a different page on the same website or to external websites and resources.

Whereas a button keeps the user within their current journey or move them to the next or previous step in that journey. They often trigger actions that support completing a task, like submitting a form, confirming an action, changing content or loading new content without disrupting the flow.

Best practices

DoUse links thoughtfully and as few as possible.
Don'tOverwhelm users with too many distracting links, that might interrupt their journey.

Mehr zu Lieferzeiten findest du in unseren Versandinfos. Die Lieferung ist ab 29 € kostenlos.

DoUse inline Link when surrounded by continuous text.

Mehr zu Lieferzeiten findest du in unseren Versandinfos. Die Lieferung ist ab 29 € kostenlos.

CautionAvoid using the secondary inline Link when surrounded by continuous text because it is less visible.
DoUse underlined link on color.
Don'tUse primary or secondary link on color.
DoUse links with one line.
CautionAvoid line breaks within the same link. Otherwise it can be perceived as two separate links.

Achte beim Kauf auf das FSC®-Label.

DoUse bold text to highlight information.

Achte beim Kauf auf das FSC®-Label.

Don'tUnderline text that is not a link to highlight information.

Mehr dazu in unseren Versandinfos für deine Bestellung.

DoUse the same size for link and text.

Mehr dazu in unseren Versandinfos für deine Bestellung.

Don'tUse different size for link and text.
DoUse same link styles in the same context.
Don'tMix different link styles in the same context.

Content guidelines

DoUse specific labels that clearly convey the link's function or destination.
Don'tUse generic or vague labels, such as "Hier klicken", "Jetzt entdecken" or "Mehr erfahren".
DoKeep link labels short concise.
Don'tUse lengthy sentences with punctuation marks for the label.

Accessibility

Be aware, that link 50 and 75 have an undersized as per WCAG SC 2.5.8 Target Size. That means that they have to maintain enough spacing of 24px from the center of the target to adjacent links. For that reason they have to maintain 8px vertical spacing to each other and can not be used within other interactive elements like cards.

Every small link keeps a free 24 × 24px target area

CautionUse enough spacing spacing for link 50 and 75 to maintain the a dead space of 24×24px.
Don'tUse links within other interactive elements like cards.

For information on accessibility, refer to the [technical documentation](https://static.otto.de/assets-storybook/iframe.html?viewMode=docs&id=components-link--overview&globals=#accessibility:~:text=user%20experience%20guidelines.-,Accessibility,-The%20link%20componento the technical documentation.).

Status

Implementation

Note: For full technical documentation of this component, visitStorybook/Link.

Live demo

Deine Rücksendung

Du hast 30 Tage Zeit, deine Bestellung kostenlos zurückzuschicken. Melde die Rücksendung in deinem Kundenkonto an und gib das Paket bei Hermes ab.

Rücksendung anmelden
LiveReal OTTO components, rendered by the OTTO component runtime
HTML
<div class="on-frame" style="margin:0;padding:24px">
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));gap:16px;max-width:880px;margin:0 auto;align-items:start">
<oc-block-v2><div style="display:grid;gap:12px">
  <p class="oc-headline-100">Deine Rücksendung</p>
  <p class="oc-copy-100">Du hast 30 Tage Zeit, deine Bestellung kostenlos zurückzuschicken. Melde die Rücksendung in <oc-link-v2 size="inherit"><a href="#">deinem Kundenkonto</a></oc-link-v2> an und gib das Paket bei Hermes ab.</p>
  <oc-link-v2 icon-right="arrow-right"><a href="#">Rücksendung anmelden</a></oc-link-v2>
</oc-block-v2>
<oc-block-v2><div style="display:grid;gap:12px">
  <p class="oc-headline-100">Hilfe &amp; Service</p>
  <div style="display:grid;gap:12px"><oc-link-v2 variant="secondary" icon-left="order-shipped"><a href="#">Wo ist meine Bestellung?</a></oc-link-v2><oc-link-v2 variant="secondary" icon-left="payment-invoice"><a href="#">Rechnung herunterladen</a></oc-link-v2><oc-link-v2 variant="secondary" icon-left="delivery-express"><a href="#">Versandkosten und Lieferzeiten</a></oc-link-v2><oc-link-v2 variant="secondary" icon-left="person-callcenter"><a href="#">Kontakt zum Kundenservice</a></oc-link-v2></div>
</oc-block-v2>

Code

Version Tag Status API
v2 <oc-link-v2> Stable, allowed for generation LinkV2

Overview (v2)

The link component provides a clickable text element with attributes for setting the URL, base64-encoded URL for SEO purposes, and ARIA label for accessibility. The component emits a click event when you interact with it. You can configure the component to behave as a button and trigger an action instead of navigating to a new page.

Default variation
<oc-link-v2>
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
Configuration

The link component offers a variety of styling variants such as primary, secondary, over-color, and over-color-bold. This component is configurable, allowing you to tailor its features and appearance to your specific needs. To explore all the available options and adjust the component, use the component configurator. You can see the changes affect the component in real-time.

Usage guidelines

Before integrating the link component into your project, make sure you have correctly installed the OTTO components package. Look through the variations page for examples of possible component variations. Here, you can discover both common and specific variations that address different use cases.

Info

See the Link UX documentation for detailed user experience guidelines.

Accessibility

The link component comes with a set of built-in accessibility features to ensure a seamless experience for all users.

Use oc-aria-label

To make the link recognizable for screen readers, use the oc-aria-label attribute to provide clear and descriptive context information. See the general accessibility documentation for guidance on using oc-aria-label, including how it works with link and masked link behavior.

The inline variation of the link component is designed to be used within text content, allowing it to blend seamlessly with surrounding text. It is particularly useful for providing additional information or context without disrupting the flow of the content.

Note

This is automatically set to true if the link is used inside a p tag or is surrounded by text nodes.

To override this behavior, set the inline attribute to false or true explicitly.

See Link behavior and masked links in the general accessibility documentation for how oc-aria-label is applied in these scenarios.

When testing links with base64-encoded hrefs, you can use the exposed APIs to simulate user interactions:

// In your test
const linkElement = document.querySelector("oc-link-v2[base64-href]");

// Unmask the link
linkElement.unmask();

// Verify the href is correct
expect(linkElement.href).toBe("https://example.com/target");

// Simulate a complete user interaction
linkElement.goto();
Programmatic navigation

Trigger navigation programmatically without requiring user interaction:

const linkElement = document.querySelector("oc-link-v2");

// Navigate immediately
linkElement.click();

// Or with unmasking and focusing
linkElement.goto();
Custom event handling

Dispatch custom events for tracking or analytics:

const linkElement = document.querySelector("oc-link-v2");

// Dispatch a tracking event before navigation
const trackingEvent = new CustomEvent("link-interaction", {
  detail: {
    timestamp: Date.now(),
    linkText: linkElement.textContent,
  },
});
linkElement.dispatch(trackingEvent);
Accessibility automation

Programmatically manage focus for accessibility features:

// Focus the first link in a navigation menu
const firstLink = document.querySelector("nav oc-link-v2");
firstLink.focus();

// Focus the next link when arrow key is pressed
const nextLink = firstLink.nextElementSibling;
if (nextLink && nextLink.tagName === "OC-LINK-V2") {
  nextLink.focus();
}
Implementation details

The APIs automatically determine which element to operate on:

  1. Light DOM element: If an <a> element is slotted into the default slot, methods are called on that element
  2. Shadow DOM element: If the link is rendered using the href or base64-href attributes, methods are called on the shadow DOM anchor element
  3. Button mode: If as-button is set, methods are called on the shadow DOM button element

The APIs are designed to be safe to call:

  • If the underlying element does not exist, methods return undefined without throwing errors
  • If the requested method does not exist on the element, no error is thrown
  • Only if the underlying method itself throws an error will that error propagate to the caller
const linkElement = document.querySelector("oc-link-v2");

// Safe to call even if the method doesn't exist
const result = linkElement.invoke("nonExistentMethod");
console.log(result); // undefined

// Errors from the underlying method are still thrown
try {
  linkElement.invoke("methodThatThrows");
} catch (error) {
  console.error("Method threw an error:", error);
}

Configuration (v2)

Configure the link component with the controls below and see the changes live in the preview canvas. Click the Show code button within the preview canvas to see the source code for the current component configuration.

<oc-link-v2>
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>

Interactive configurator (Storybook controls); every option is listed in the API section of this file.

Migration (v2)

The oc-link component has been updated from oc-link-v1 to oc-link-v2. This migration guide provides a step-by-step guide to update your project to the latest version.

Skip to:

What's new
Web component

The link is now a proper web component instead of a CSS-only class, providing:

  • Encapsulated styling
  • Consistent behavior across the application
  • Better integration with other Otto Components

The <a> tag is placed inside the component slot, preserving native link behavior for search engine crawlers.

API changes
Changed structure
v1 (CSS class) v2 (Web Component) Notes
<a class="oc-link-v1"> <oc-link-v2><a>...</a></oc-link-v2> Link moved to slot
<button class="oc-link-v1"> <oc-link-v2 as-button> Component handles button styling
oc-link-v1--primary variant="primary" (default) Default variant
oc-link-v1--secondary variant="secondary" No change
oc-link-v1--underlined variant="underlined" No change
oc-link-v1--underlined-bold variant="underlined-bold" No change
oc-link-v1--size-50 size="50" No change
oc-link-v1--size-75 size="75" No change
oc-link-v1--size-100 size="100" No change
oc-link-v1--size-125 size="125" No change
How to migrate

Instead of using a div with the oc-link-v1 class, use the oc-link-v2 component tag to create a link. The oc-link-v2 component can be used as a link or button by adding the href or as-button attribute respectively.

Here's a table mapping deprecated CSS classes to their corresponding replacement attributes in the new version:

CSS-Class (V1) Attribute (V2) Notes
oc-link-v1--primary variant="primary" (default) Default variant
oc-link-v1--secondary variant="secondary" No change
oc-link-v1--underlined variant="underlined" No change
oc-link-v1--underlined-bold variant="underlined-bold" No change
oc-link-v1--size-50 size="50" No change
oc-link-v1--size-75 size="75" No change
oc-link-v1--size-100 size="100" No change
oc-link-v1--size-125 size="125" No change

To migrate a basic link, replace the anchor tag <a> including the oc-link-v1 class with the oc-link-v2 component tag and keep the href attribute.

<!-- From: -->
<a class="oc-link-v1" href="#">My Link</a>
<!-- To: -->
<oc-link-v2>
  <a href="#">My Link</a>
</oc-link-v2>

To migrate a link with a variant, replace the anchor tag <a> including the oc-link-v1 class with the oc-link-v2 component tag and add the variant attribute with the desired value.

<!-- From: -->
<a class="oc-link-v1 oc-link-v1--secondary" href="#">My Link</a>
<!-- To: -->
<oc-link-v2 variant="secondary">
  <a href="#">My Link</a>
</oc-link-v2>

To migrate a link with a size, replace the anchor tag <a> including the oc-link-v1 class with the oc-link-v2 component tag and add the size attribute with the desired value.

<!-- From: -->
<a class="oc-link-v1 oc-link-v1--size-50" href="#">My Link</a>
<!-- To: -->
<oc-link-v2 size="50">
  <a href="#">My Link</a>
</oc-link-v2>

To migrate a link as a button, replace the button tag including the oc-link-v1 class with the oc-link-v2 component tag and add the as-button attribute.

<!-- From: -->
<button class="oc-link-v1">My Link</button>
<!-- To: -->
<oc-link-v2 as-button="">My Link</oc-link-v2>

API v2

The Link component provides a clickable text element with attributes for setting the URL, base64 encoded URL for SEO purposes, ARIA label for accessibility, and emitting a click event when interacted with. It can also behave as a button and trigger an action instead of navigating to a new page.

The native a tag is moved to the default slot for SEO purposes.

Attributes / properties
Attribute Type Default Required Description
variant "primary" | "secondary" | "sale" | "inverted" | "on-color" | "on-color-bold" | "over-color" | "over-color-bold" | "inverted-bold" | "underlined" | "underlined-bold" "primary" no Sets the main styling of the link component.

Can be one of: primary, secondary, over-color, over-color-bold, inverted, inverted-bold. Deprecated: underlined, underlined-bold, on-color, on-color-bold.
size "50" | "100" | "75" | "125" | "inherit" "100" no Sets the font of the link component.
Can be one of: 50, 75, 100, 125 or inherit.

If you want to use the font size of the parent element, set the size attribute to inherit.
icon-left icon name (427 values; see Icon list in `storybook/components/icon/README.md`) undefined no Sets the left icon This applies only when a size attribute is set.

Note: inherit is not supported.
icon-right icon name (427 values; see Icon list in `storybook/components/icon/README.md`) undefined no Sets the right icon This applies only when a size attribute is set.

Note: inherit is not supported.
icon-gap string "var(--oc-semantic-spacing-relative-25)" no Sets the gap between the icons and the text content of the link. This applies only when at least one of the icons is set.
inline "true" | "false" no Sets the link to be inline. It renders with an underline in all states.

Note: This is automatically set to true if the link is used inside a p tag or is surrounded by text nodes.
href string undefined no Deprecated: Use an a tag in the default slot instead.

Visit SEO optimization techniques for more information.

Sets the link target of the link.
base64-href string undefined no Sets the base64 encoded link target of the link component. Use this attribute to prevent search engines from indexing the link target.
target "_blank" | "_self" | "_parent" | "_top" undefined no Sets the target attribute of the link.

Note Only applies when href or base64Href is set.
rel string undefined no Sets the rel attribute of the link.

Note Only applies when href or base64Href is set.
as-button boolean false no Determines if the link behaves as a button. Set to true to make the link behave as a button and trigger an action instead of navigating to a new page.
oc-aria-label string undefined no Sets the ARIA label of the link.

Note This attribute is not available when using an a tag in the default slot. Instead, use the aria-label attribute on the a tag in the default slot.
Slots
Slot Required Description
default yes Sets the content of the link component.
Events
Event Detail type Description
click PointerEvent Clicking the link or pressing the Enter or Space key while the link is focused triggers the click event. Use this event in case the as-button attribute is set to true.
oc-property-change OcLinkV2Events["oc-property-change"] Whenever a property value changes, this event triggers. Use this event to track all property changes within the component.

Refer to the Events documentation for more information.
oc-mount { component: string; } Fired when the component is mounted to the DOM. The event is fired when the onMount hook of the component is called by the runtime.
oc-unmount { component: string; } Fired when the component is unmounted from the DOM. The event is fired when the function returned by the onMount hook of the component is called by the runtime.
Methods
  • focus: () => void

    Calls the native focus() method on the underlying element.

    This is a convenience method that internally uses invoke("focus").

    Returns: void

    Example:

    const link = document.querySelector("oc-link-v2");
    link.focus();
    
  • click: () => void

    Calls the native click() method on the underlying element.

    This is a convenience method that internally uses invoke("click").

    Returns: void

    Example:

    const link = document.querySelector("oc-link-v2");
    link.click();
    
  • goto: () => void

    This is a shorthand function that combines three operations:

    1. Unmasks the link href (if it's base64-encoded)
    2. Focuses the link element
    3. Clicks the link element

    This method simulates a complete user interaction with the link. It is especially useful for testing masked links.

    Returns: void

    Example:

    const link = document.querySelector("oc-link-v2[base64-href]");
    link.goto();
    
  • unmask: () => void

    Calls the underlying unmasking function to decode and apply the base64-encoded href. This is used when the link is rendered with the base64-href attribute for SEO purposes. Normally, unmasking happens automatically on user interaction, but this method allows you to trigger it programmatically for integration testing or other scenarios.

    Returns: void

    Example:

    const linkElement = document.querySelector("oc-link-v2[base64-href]");
    
    // Unmask the link programmatically
    linkElement.unmask();
    
    // Now the href is accessible
    console.log(linkElement.href);
    
  • dispatch: <E extends Event>(event: E) => void

    Calls dispatchEvent on the underlying element to dispatch the given event. This is useful for testing purposes, to simulate user interactions or to trigger custom events on the underlying element.

    Parameters:

    • event: E The event to dispatch on the underlying element

    Returns: void

    Example:

    const linkElement = document.querySelector("oc-link-v2");
    
    // Dispatch a custom event
    const customEvent = new CustomEvent("custom-action", {
      detail: { action: "track-click" },
    });
    linkElement.dispatch(customEvent);
    
    // Dispatch a native event
    const mouseEvent = new MouseEvent("mouseenter");
    linkElement.dispatch(mouseEvent);
    
  • invoke: <R>(methodIdentifier: string, ...args: unknown[]) => R

    Genric helper method used to invoke (call) functions on the underlying element which currently acts as link in the link component. This is useful in cases where there is no light dom element of the state of the link is not deterministic.

    The method will invoke the function on either a light dom link. element if it exists, or on the underlying element inside shadow dom in cases there is no light dom anchor.

    The result of the method depends on the implementation of the underlying element and must be assured by the consumer of the component.

    If there is no suitable element or method to invoke, it will return undefined. This function will only produce errors if the underlying method throws an error.

    The function will not throw if the invocation is not possible.

    Parameters:

    • methodIdentifier: string The name of the method to invoke on the underlying element
    • args: unknown[] The arguments to pass to the method

    Returns: R The result of the method invocation, or undefined if the element or method does not exist

CSS custom properties
Custom property Default Description
--icon-gap "var(--oc-semantic-spacing-relative-25)" Sets the gap between the icons and the text content of the link. This applies only when at least one of the icons is set.

Variations (v2)

Variations

Listed below are the most common variations of the link component as well as specific component variations for different use cases.

You can explore all available options using the component configurator, adjust the component to your needs, and see the changes live in a preview canvas.

Default

Story: components-link-variations--default · tags: components

The default configuration represents the most common link type and uses the href attribute for navigation.

<oc-link-v2>
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
Secondary

Story: components-link-variations--secondary · tags: components

The secondary variant follows the same pattern as the default variant but with a different styling.

Args: variant=secondary

<oc-link-v2 variant="secondary">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
Over Color variant

Story: components-link-variations--over-color-variant · tags: components

The over-color variant follows the same pattern as the default variant but with an underline added, to be used on colored surfaces such as banners.

Args: variant=over-color

<oc-link-v2 variant="over-color">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
Over Color variant bold

Story: components-link-variations--over-color-variant-bold · tags: components

The over-color bold variant follows the same pattern as the default variant but with a bold font weight and an underline added.

Args: variant=over-color-bold

<oc-link-v2 variant="over-color-bold">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
Inverted

Story: components-link-variations--inverted · tags: components

The inverted variant follows the same pattern as the default variant but with an inverted color added, to be used on dark contrast backgrounds to improve readability

Args: variant=inverted

<oc-link-v2 variant="inverted">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
Inline

Story: components-link-variations--inline · tags: components

The inline attribute allows the link to be rendered inline with a decorative underline.

Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie sie aussehen. Manchmal benutzt man Worte wie Hamburgefonts, Rafgenduks oder Handgloves, um Schriften zu testen. Manchmal Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese Sätze »Pangrams«. Sehr bekannt ist dieser: The quick brown fox jumps over the lazy old dog . Oft werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and Wefox™ are testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In Lateinisch sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit 1975 fehlen in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem Jahr 2034 Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245 € oder 368 $ bestraft. Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes Feld sind OpenType-Funktionalitäten. Je nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder Ligaturen (sehr pfiffig) nicht richtig dargestellt werden.

Ich bin nicht teil des Textfluss, also sollte ich auch keinen Unterstrich bekommen!
HTML
<div style="display: flex;  gap: 16px;">
<div style="max-width: 456px; border: 1px solid #ccc; padding: 16px;">
  <span class="oc-copy-100">
    Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie
    sie aussehen. Manchmal benutzt man Worte wie
    <oc-link-v2 size="inherit" inline="true">Hamburgefonts</oc-link-v2>,
    <oc-link-v2 size="inherit" inline="true">Rafgenduks</oc-link-v2> oder
    <oc-link-v2 size="inherit" inline="true">Handgloves</oc-link-v2>, um Schriften zu
    testen. Manchmal Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese
    Sätze »Pangrams«. Sehr bekannt ist dieser: The quick brown fox jumps over the lazy
    <oc-link-v2 variant="primary" icon-right="smiley-happy" inline="true"
      >old dog</oc-link-v2
    >
    . Oft werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and
    Wefox™ are testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In
    Lateinisch sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit
    1975 fehlen in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem
    Jahr 2034 Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245
    € oder 368 $
    <oc-link-v2 variant="primary" icon-right="smiley-negative" inline="true"
      >bestraft</oc-link-v2
    >. Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren
    Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes
    Feld sind
    <oc-link-v2 variant="secondary" size="inherit" inline="true"
      >OpenType-Funktionalitäten</oc-link-v2
    >. Je nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder
    Ligaturen (sehr pfiffig) nicht richtig dargestellt werden.
  </span>
<br />
<oc-link-v2 size="inherit"
>Ich bin nicht teil des Textfluss, also sollte ich auch keinen Unterstrich
bekommen!</oc-link-v2
>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Inline",
  argTypes: hideControlsBadge(Metadata),
  parameters: {
    controls: {
      disabled: true
    }
  },
  render() {
    return html`
      <div style="display: flex;  gap: 16px;">
        <div style="max-width: 456px; border: 1px solid #ccc; padding: 16px;">
          <span class="oc-copy-100">
            Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie
            sie aussehen. Manchmal benutzt man Worte wie
            <oc-link-v2 size="inherit" inline="true">Hamburgefonts</oc-link-v2>,
            <oc-link-v2 size="inherit" inline="true">Rafgenduks</oc-link-v2> oder
            <oc-link-v2 size="inherit" inline="true">Handgloves</oc-link-v2>, um Schriften zu
            testen. Manchmal Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese
            Sätze »Pangrams«. Sehr bekannt ist dieser: The quick brown fox jumps over the lazy
            <oc-link-v2 variant="primary" icon-right="smiley-happy" inline="true"
              >old dog</oc-link-v2
            >
            . Oft werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and
            Wefox™ are testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In
            Lateinisch sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit
            1975 fehlen in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem
            Jahr 2034 Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245
            € oder 368 $
            <oc-link-v2 variant="primary" icon-right="smiley-negative" inline="true"
              >bestraft</oc-link-v2
            >. Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren
            Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes
            Feld sind
            <oc-link-v2 variant="secondary" size="inherit" inline="true"
              >OpenType-Funktionalitäten</oc-link-v2
            >. Je nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder
            Ligaturen (sehr pfiffig) nicht richtig dargestellt werden.
          </span>
        </div>
      </div>
      <br />
      <oc-link-v2 size="inherit"
        >Ich bin nicht teil des Textfluss, also sollte ich auch keinen Unterstrich
        bekommen!</oc-link-v2
      >
    `;
  }
}
Inverted bold

Story: components-link-variations--inverted-bold · tags: components

The inverted bold variant follows the same pattern as the default variant but with a bold font weight and an inverted color added, to be used on dark contrast backgrounds to improve readability

Args: variant=inverted-bold

<oc-link-v2 variant="inverted-bold">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
With button behavior

Story: components-link-variations--with-button-behavior · tags: components

Variation of the default configuration using the as-button attribute to trigger an action when clicked instead of navigating to a new page.

Args: as-button=true, defaultSlot=Link

Link
HTML
<oc-link-v2 as-button>Link</oc-link-v2>
With left icon

Story: components-link-variations--with-left-icon · tags: components

Variation of the default configuration with a left icon using the icon-type-left attribute.

Args: icon-left=smiley-positive

<oc-link-v2 icon-left="smiley-positive">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>
With right icon

Story: components-link-variations--with-right-icon · tags: components

Variation of the default configuration with a right icon using the icon-type-right attribute.

Args: icon-right=smiley-positive

<oc-link-v2 icon-right="smiley-positive">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#'>Link</a>
</oc-link-v2>

Story: components-link-variations--with-masked-link-behavior · tags: components

The link component as a masked link. Search engines will not detect the href.

Args: base64-href=Iw==, defaultSlot=Link

Link
HTML
<oc-link-v2 base64-href="Iw==">Link</oc-link-v2>

Story: components-link-variations--with-link-switch-behavior · tags: components

The link component as a link with switch behavior. Search engines will detect the href, while users receive the Base64-encoded version.

Args: base64-href=Iz92YXJpYW50PWZvbw==, defaultSlot=<!--Search engines will detect the href, while users receive the Base64-encoded version.--><a href='#'>Link</a>

<oc-link-v2 base64-href="Iz92YXJpYW50PWZvbw==">
  <!--Search engines will detect the href, while users receive the Base64-encoded version.--><a href='#'>Link</a>
</oc-link-v2>

Story: components-link-variations--link-size-inherit · tags: components

Variation link size inherit using the size attribute with the value inherit. This will use the font size of the parent element.

Args: size=inherit, defaultSlot=<a href='#'>Link within a headline</a>

HTML
<h1 class="oc-headline-300">
<oc-link-v2 size="inherit" style="display: block"><a href='#'>Link within a headline</a></oc-link-v2>
</h1>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Link size inherit",
  args: {
    size: "inherit",
    defaultSlot: "<a href='#'>Link within a headline</a>"
  },
  render({
    defaultSlot,
    ...props
  }) {
    return html`
      <h1 class="oc-headline-300">
        <oc-link-v2 ${spread(props)} style="display: block">${unsafeHTML(defaultSlot)}</oc-link-v2>
      </h1>
    `;
  }
}

Story: components-link-variations--demo-inline-links · tags: components, skip-test

Demo with inline links.

Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie sie aussehen. Manchmal benutzt man Worte wie Hamburgefonts , Rafgenduks oder Handgloves, um Schriften zu testen. Manchmal Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese Sätze »Pangrams«. Sehr bekannt ist dieser: The quick brown fox jumps over the lazy old dog . Oft werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and Wefox™ are testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In Lateinisch sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit 1975 fehlen in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem Jahr 2034 Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245 € oder 368 $ bestraft. Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes Feld sind OpenType-Funktionalitäten. Je nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder Ligaturen (sehr pfiffig) nicht richtig dargestellt werden.

Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie sie aussehen. Manchmal benutzt man Worte wie Hamburgefonts, Rafgenduks oder Handgloves, um Schriften zu testen. Manchmal Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese Sätze »Pangrams«. Sehr bekannt ist dieser: The quick brown fox jumps over the lazy old dog. Oft werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and Wefox™ are testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In Lateinisch sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit 1975 fehlen in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem Jahr 2034 Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245 € oder 368 $ bestraft. Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes Feld sind OpenType-Funktionalitäten. Je nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder Ligaturen (sehr pfiffig) nicht richtig dargestellt werden.

HTML
<div style="display: flex;  gap: 16px;">
<div style="max-width: 456px; border: 1px solid #ccc; padding: 16px;">
  <p class="oc-copy-100">
    Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie
    sie aussehen. Manchmal benutzt man Worte wie
    <oc-link-v2 inline="false" size="inherit"> <a href="#">Hamburgefonts</a> </oc-link-v2>,
    <oc-link-v2 size="inherit">Rafgenduks</oc-link-v2> oder
    <oc-link-v2 size="inherit">Handgloves</oc-link-v2>, um Schriften zu testen. Manchmal
    Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese Sätze »Pangrams«.
    Sehr bekannt ist dieser: The quick brown fox jumps over the lazy
    <oc-link-v2 variant="primary" icon-right="smiley-happy">old dog</oc-link-v2>
    . Oft werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and
    Wefox™ are testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In
    Lateinisch sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit
    1975 fehlen in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem
    Jahr 2034 Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245
    € oder 368 $
    <oc-link-v2 variant="primary" icon-right="smiley-negative">bestraft</oc-link-v2>.
    Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren
    Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes
    Feld sind
    <oc-link-v2 variant="secondary" size="inherit">OpenType-Funktionalitäten</oc-link-v2>.
    Je nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder
    Ligaturen (sehr pfiffig) nicht richtig dargestellt werden.
  </p>
<div
  style="max-width: 456px; border: 1px solid #ccc; padding: 16px; background-color: var(--oc-semantic-color-inverted-background) !important;"
>
  <p class="oc-copy-100" style="color: var(--oc-semantic-color-text-inverted) !important;">
    Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie
    sie aussehen. Manchmal benutzt man Worte wie
    <oc-link-v2 inline="false" variant="inverted" size="inherit">Hamburgefonts</oc-link-v2>,
    <oc-link-v2 variant="inverted" size="inherit">Rafgenduks</oc-link-v2> oder
    <oc-link-v2 variant="inverted" size="inherit">Handgloves</oc-link-v2>, um Schriften zu
    testen. Manchmal Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese
    Sätze »Pangrams«. Sehr bekannt ist dieser: The quick brown fox jumps over the lazy
    <oc-link-v2 variant="inverted" icon-right="smiley-happy">old dog</oc-link-v2>. Oft
    werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and Wefox™ are
    testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In Lateinisch
    sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit 1975 fehlen
    in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem Jahr 2034
    Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245 € oder
    368 $ <oc-link-v2 icon-right="smiley-negative" variant="inverted">bestraft</oc-link-v2>.
    Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren
    Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes
    Feld sind
    <oc-link-v2 variant="inverted" size="inherit">OpenType-Funktionalitäten</oc-link-v2>. Je
    nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder Ligaturen
    (sehr pfiffig) nicht richtig dargestellt werden.
  </p>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: Inline links",
  tags: ["skip-test"],
  argTypes: hideControlsBadge(Metadata),
  parameters: {
    chromatic: {
      hideInChromatic: true
    },
    controls: {
      disabled: true
    }
  },
  render() {
    return html`
      <div style="display: flex;  gap: 16px;">
        <div style="max-width: 456px; border: 1px solid #ccc; padding: 16px;">
          <p class="oc-copy-100">
            Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie
            sie aussehen. Manchmal benutzt man Worte wie
            <oc-link-v2 inline="false" size="inherit"> <a href="#">Hamburgefonts</a> </oc-link-v2>,
            <oc-link-v2 size="inherit">Rafgenduks</oc-link-v2> oder
            <oc-link-v2 size="inherit">Handgloves</oc-link-v2>, um Schriften zu testen. Manchmal
            Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese Sätze »Pangrams«.
            Sehr bekannt ist dieser: The quick brown fox jumps over the lazy
            <oc-link-v2 variant="primary" icon-right="smiley-happy">old dog</oc-link-v2>
            . Oft werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and
            Wefox™ are testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In
            Lateinisch sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit
            1975 fehlen in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem
            Jahr 2034 Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245
            € oder 368 $
            <oc-link-v2 variant="primary" icon-right="smiley-negative">bestraft</oc-link-v2>.
            Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren
            Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes
            Feld sind
            <oc-link-v2 variant="secondary" size="inherit">OpenType-Funktionalitäten</oc-link-v2>.
            Je nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder
            Ligaturen (sehr pfiffig) nicht richtig dargestellt werden.
          </p>
        </div>
        <div
          style="max-width: 456px; border: 1px solid #ccc; padding: 16px; background-color: var(--oc-semantic-color-inverted-background) !important;"
        >
          <p class="oc-copy-100" style="color: var(--oc-semantic-color-text-inverted) !important;">
            Dies ist ein Typoblindtext. An ihm kann man sehen, ob alle Buchstaben da sind und wie
            sie aussehen. Manchmal benutzt man Worte wie
            <oc-link-v2 inline="false" variant="inverted" size="inherit">Hamburgefonts</oc-link-v2>,
            <oc-link-v2 variant="inverted" size="inherit">Rafgenduks</oc-link-v2> oder
            <oc-link-v2 variant="inverted" size="inherit">Handgloves</oc-link-v2>, um Schriften zu
            testen. Manchmal Sätze, die alle Buchstaben des Alphabets enthalten - man nennt diese
            Sätze »Pangrams«. Sehr bekannt ist dieser: The quick brown fox jumps over the lazy
            <oc-link-v2 variant="inverted" icon-right="smiley-happy">old dog</oc-link-v2>. Oft
            werden in Typoblindtexte auch fremdsprachige Satzteile eingebaut (AVAIL® and Wefox™ are
            testing aussi la Kerning), um die Wirkung in anderen Sprachen zu testen. In Lateinisch
            sieht zum Beispiel fast jede Schrift gut aus. Quod erat demonstrandum. Seit 1975 fehlen
            in den meisten Testtexten die Zahlen, weswegen nach TypoGb. 204 § ab dem Jahr 2034
            Zahlen in 86 der Texte zur Pflicht werden. Nichteinhaltung wird mit bis zu 245 € oder
            368 $ <oc-link-v2 icon-right="smiley-negative" variant="inverted">bestraft</oc-link-v2>.
            Genauso wichtig in Typoblindtexten sind mittlerweile auch Âçcèñtë, die in neueren
            Schriften aber fast immer enthalten sind. Ein wichtiges aber schwierig zu integrierendes
            Feld sind
            <oc-link-v2 variant="inverted" size="inherit">OpenType-Funktionalitäten</oc-link-v2>. Je
            nach Software und Voreinstellungen können eingebaute Kapitälchen, Kerning oder Ligaturen
            (sehr pfiffig) nicht richtig dargestellt werden.
          </p>
        </div>
      </div>
    `;
  }
}

Interaction tests (LinkV2.interactions.stories.ts)

Interaction test stories (automated tests, not usage patterns).

Should Handle Base 64 Href

Story: components-link-interaction-tests--should-handle-base-64-href · tags: play-fn

Link
HTML
<oc-link-v2 base64-href="L2Zvbw==">Link</oc-link-v2>
Story source (TypeScript, verbatim from Storybook)
{
  render() {
    return html`<oc-link-v2 base64-href="L2Zvbw==">Link</oc-link-v2>`;
  },
  async play({
    canvasElement
  }) {
    const ocLink = canvasElement.getElementsByTagName("oc-link-v2").item(0)!;
    ocLink.focus();
    await tick();

    // instead of the div element there should now be an anchor element
    const linkElement = ocLink.shadowRoot!.children.item(0)! as HTMLAnchorElement;
    await expect(linkElement.tagName).toBe("A");

    // anchor element inside the shadow root should have the correct href attribute
    await expect(linkElement.getAttribute("href")).toBe(`/foo`);

    // anchor element inside the shadow root should have the same fully href as the host
    await expect(ocLink.href).toBe(`${window.location.origin}/foo`);
    await expect(linkElement.href).toBe(`${window.location.origin}/foo`);
  }
}

Should Handle Base 64 Href With An A Tag

Story: components-link-interaction-tests--should-handle-base-64-href-with-an-a-tag · tags: play-fn

<oc-link-v2 base64-href=${btoa("/foo")}><a href="#">Link</a></oc-link-v2>
Story source (TypeScript, verbatim from Storybook)
{
  render() {
    return html`<oc-link-v2 base64-href=${btoa("/foo")}><a href="#">Link</a></oc-link-v2>`;
  },
  async play({
    canvasElement
  }) {
    const ocLink = canvasElement.getElementsByTagName("oc-link-v2").item(0)!;
    const anchor = canvasElement.getElementsByTagName("a").item(0)!;
    anchor.focus();
    await tick();

    // the div element should still be there
    const interactiveElement = ocLink.shadowRoot!.children.item(0)!;
    await expect(interactiveElement.tagName).toBe("DIV");

    // The anchor element should have the correct href attribute
    await expect(anchor.getAttribute("href")).toBe(`/foo`);
    await expect(anchor.href).toBe(`${window.location.origin}/foo`);
  }
}