OTTODesign System

Code

Icon Button

Storybook group: Components · Sidebar path: Components/Icon Button · Extracted 28.09.2026

Version Tag Status API
v3 <oc-icon-button-v3> Stable, allowed for generation IconButtonV3
v2 <oc-icon-button-v2> Deprecated, NOT allowed for generation IconButtonV2
v1 <oc-icon-button-v1> Deprecated, NOT allowed for generation IconButtonV1

Only the latest version (v3) is allowed for generation. Older versions are kept for reference and are deprecated.

Overview (v3)

Source: ./src/components/icon-button/v3/Overview.mdx

Icon Button

The icon button component provides an interactive icon on a circular white background, with attributes for setting the icon, size, ARIA label, a disabled state and emitting a click event when interacted with.

Default variation

Story Default:

<oc-icon-button-v3 icon="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v3>

Configuration

The icon button 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 and see the changes affect the component in real-time.

Usage guidelines

Before integrating the icon button 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 Icon Button UX documentation for detailed user experience guidelines.

Layout considerations

This component has an extended hitbox. The touch area extends beyond its bounding box, so it may be activated when the user clicks or taps outside the visible component area. Ensure sufficient margin around the component to prevent unintended interactions with adjacent elements.

Accessibility

The icon button 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 icon button 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.

Further reading

Configuration (v3)

Source: ./src/components/icon-button/v3/Configuration.mdx

Icon Button configuration

Configure the icon button 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.

Story Default:

<oc-icon-button-v3 icon="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v3>

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

Migration (v3)

Source: ./src/components/icon-button/v3/Migration.mdx

Migration from Icon Button v2 to v3

The oc-icon-button component has been updated from oc-icon-button-v2 to oc-icon-button-v3. This migration guide provides step-by-step instructions to update your project to the latest version.

Skip to:

What's new

Built-in tooltip

The oc-icon-button-v3 includes a built-in tooltip via the label attribute:

<oc-icon-button-v3 icon="wishlist" label="Add to wishlist"></oc-icon-button-v3>
New variants

Additional styling variants are available for different use cases.

API changes

Removed attributes
v2 Attribute v3 Equivalent Notes
elevation="100" elevation-level="canvas" Renamed to semantic values
elevation="200" elevation-level="above" Renamed to semantic values
elevation="300" elevation-level="sticky" Renamed to semantic values
href Use an <a> tag inside the default slot Moved to slot for better SEO

How to migrate

The oc-icon-button-v3 removes the deprecated properties elevation and href. Additionally, it brings several new variants and a built-in tooltip.

Migrate a basic icon button
<!-- From: -->
<oc-icon-button-v2 icon="wishlist" elevation="200"></oc-icon-button-v2>
<!-- To: -->
<oc-icon-button-v3 icon="wishlist" elevation-level="above"></oc-icon-button-v3>
Migrate an icon button with href
<!-- From: -->
<oc-icon-button-v2 icon="wishlist" href="/wishlist"></oc-icon-button-v2>
<!-- To: -->
<oc-icon-button-v3 icon="wishlist">
  <a href="/wishlist"></a>
</oc-icon-button-v3>

API v1 (v1, deprecated, not for generation)

Source: ./src/components/icon-button/v1/IconButtonV1.API.g.mdx

Icon Button v1 API

API: <oc-icon-button-v1> (IconButtonV1)

The Icon Button component provides an interactive icon on a circular white background, with attributes for setting the icon type, size, ARIA label, a disabled state and emitting a click event when interacted with.

Attributes / properties
Attribute Type Default Required Description
variant "default" | "transparent" | "inverted" "default" no Selects the style of icon button to be used.

Can be one of: default, transparent, and inverted.
size "50" | "100" | "25" "50" no Sets the size of the icon button. Can be one of: 25, 50, 100.
icon-type icon name (428 values; see Icon list in `storybook/components/icon/README.md`) yes Sets the displayed icon. Find all available icons here.
transparent boolean false no Deprecated: Please use the variant property instead.

DEPRECATED: When enabled, sets the variant to transparent.
disabled boolean false no Toggles the state of the icon button between enabled and disabled. Set to true to disable the button and prevent user interaction.
loading boolean false no Toggles the state of the button between loading and not loading. Set to true to enable the loading state and display a loading animation.
elevated boolean undefined no Deprecated: Please use the elevation property instead.

DEPRECATED: When enabled, sets the elevation of the icon button to 200.
elevation "100" | "200" | "300" | "0" "0" no Sets the elevation level of the icon button. Can be one of: 0, 100, 200 or 300.
icon-color string undefined no Sets the color of the displayed icon. This overrides the default color in all cases except for the disabled state.
href string undefined no Sets the link target of the icon button.
base64-href string undefined no Sets the base64 encoded link target of the energy label. Use this attribute to prevent search engines from indexing the link target.
oc-aria-label string yes Sets the ARIA label of the icon button.
Events
Event Detail type Description
click PointerEvent Clicking the icon button or pressing the Enter or Space key while the icon button is focused triggers the click event.
oc-property-change OcIconButtonV1Events["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.

API v2 (v2, deprecated, not for generation)

Source: ./src/components/icon-button/v2/IconButtonV2.API.g.mdx

Icon Button v2 API

API: <oc-icon-button-v2> (IconButtonV2)

The Icon Button component provides an interactive icon on a circular white background, with attributes for setting the icon type, size, ARIA label, a disabled state and emitting a click event when interacted with.

Attributes / properties
Attribute Type Default Required Description
variant "default" | "transparent" | "inverted-transparent" "default" no Selects the style of icon button to be used.

Can be one of: default, transparent, and inverted-transparent.
size "50" | "100" | "25" "50" no Sets the size of the icon button. Can be one of: 25, 50, 100.
icon icon name (428 values; see Icon list in `storybook/components/icon/README.md`) yes Sets the displayed icon. Find all available icons here.
disabled boolean false no Toggles the state of the icon button between enabled and disabled. Set to true to disable the button and prevent user interaction.
loading boolean false no Toggles the state of the button between loading and not loading. Set to true to enable the loading state and display a loading animation.
elevation "100" | "200" | "300" | "0" "0" no Sets the elevation level of the icon button. Can be one of: 0, 100, 200 or 300.
icon-color string undefined no Sets the color of the displayed icon. This overrides the default color in all cases except for the disabled state.
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 icon button.
base64-href string undefined no Sets the base64 encoded link target of the energy label. 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 icon button.

Note Only applies when base64Href is set.
rel string undefined no Sets the rel attribute of the icon button.

Note Only applies when base64Href is set.
oc-aria-label string yes Sets the ARIA label of the icon button.
Slots
Slot Required Description
default no Add an empty tag to change the default behavior of the icon button component.

- empty a tag: the card component behaves as a link (SEO relevant)
Events
Event Detail type Description
click PointerEvent Clicking the icon button or pressing the Enter or Space key while the icon button is focused triggers the click event.
oc-property-change OcIconButtonV2Events["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.

API v3

Source: ./src/components/icon-button/v3/IconButtonV3.API.g.mdx

Icon Button v3 API

API: <oc-icon-button-v3> (IconButtonV3)

The Icon Button component provides an interactive icon on a circular white background, with attributes for setting the icon type, size, ARIA label, a disabled state and emitting a click event when interacted with.

Attributes / properties
Attribute Type Default Required Description
variant "primary" | "secondary" | "secondary-on-color" | "secondary-over-color" | "tertiary" | "custom-color-strong" | "custom-color-soft" | "transparent" | "transparent-inverted" "secondary-over-color" no Selects the style of icon button to be used. secondary-on-color is deprecated, use secondary-over-color instead.
size "50" | "100" | "25" | "75" "50" no Sets the size of the icon button. Can be one of: 25, 50, 75, 100.
icon icon name (428 values; see Icon list in `storybook/components/icon/README.md`) yes Sets the displayed icon. Find all available icons here.
label string undefined no When set a Tooltip with the label content will be displayed on hover.
disabled boolean false no Toggles the state of the icon button between enabled and disabled. Set to true to disable the button and prevent user interaction.
loading boolean false no Toggles the state of the button between loading and not loading. Set to true to enable the loading state and display a loading animation.
success boolean false no Sets the success state of the icon-button. This is a visual state that indicates a successful action. It does not change the functionality of the icon-button.
elevation-level "canvas" | "above" | "sticky" "canvas" no Sets the elevation level of the icon button. The elevation level determines the shadow and depth of the icon button. - canvas: no shadow, icon button appears flat, to be used on frame. - above: shadow, icon button appears above other levels. - sticky: shadow, icon button appears above all other levels and is sticky.
background-color string undefined no Deprecated: The background-color attribute is deprecated. Use the CSS variable --background-color instead.

Sets the background color of the icon button.
icon-color string undefined no Deprecated: The icon-color attribute is deprecated. Use the CSS variable --icon-color instead.

Sets the color of the displayed icon. This overrides the default color in all cases except for the disabled state.
base64-href string undefined no Sets the base64 encoded link target of the icon button. 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 icon button.

Note Only applies when base64Href is set.
rel string undefined no Sets the rel attribute of the icon button.

Note Only applies when base64Href is set.
oc-aria-label string yes Sets the ARIA label of the icon button.
Slots
Slot Required Description
default no Add an empty tag to change the default behavior of the icon button component.

- empty a tag: the icon button component behaves as a link (SEO relevant)
Events
Event Detail type Description
click PointerEvent Clicking the icon button or pressing the Enter or Space key while the icon button is focused triggers the click event.
oc-property-change OcIconButtonV3Events["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.
CSS custom properties
Custom property Default Description
--background-color undefined Sets a custom background color through a CSS variable.

Note: The preferred way of using colors is via design tokens instead of hex values.

Note: This CSS variable only applies when using variant="custom-color-strong" or variant="custom-color-soft".
--icon-color undefined Sets a custom text color through a CSS variable.

Note: The preferred way of using colors is via design tokens instead of hex values.

Note: This CSS variable only applies when using variant="custom-color-strong" or variant="custom-color-soft".

Variations (v3)

Source: ./src/components/icon-button/v3/Variations.mdx

Variations

Listed below are the most common variations of the icon button 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-icon-button-variations--default · tags: components

The default configuration uses the icon=wishlist and size=50.

Args: oc-aria-label=Default icon button component

<oc-icon-button-v3 icon="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v3>

Transparent 75

Story: components-icon-button-variations--icon-button-75-transparent · tags: components

The transparent variant uses no background color for the icon button.

Args: size=75, variant=transparent, icon=wishlist, oc-aria-label=Icon button of size 75 and variant transparent

<oc-icon-button-v3 icon="wishlist" size="75" variant="transparent" oc-aria-label="Icon button of size 75 and variant transparent"></oc-icon-button-v3>

Transparent-Inverted 75

Story: components-icon-button-variations--icon-button-75-inverted · tags: components

The transparent-inverted variant features a white icon on a transparent background, suitable for dark backgrounds.

Args: size=75, variant=transparent-inverted, icon=wishlist, oc-aria-label=Icon button of size 75 and variant inverted

<oc-icon-button-v3 icon="wishlist" size="75" variant="transparent-inverted" oc-aria-label="Icon button of size 75 and variant inverted"></oc-icon-button-v3>

Transparent 50

Story: components-icon-button-variations--icon-button-50-transparent · tags: components

The transparent variant uses no background color for the icon button.

Args: size=50, variant=transparent, icon=wishlist, oc-aria-label=Icon button of size 50 and variant transparent

<oc-icon-button-v3 icon="wishlist" size="50" variant="transparent" oc-aria-label="Icon button of size 50 and variant transparent"></oc-icon-button-v3>

Transparent-Inverted 50

Story: components-icon-button-variations--icon-button-50-inverted · tags: components

The transparent-inverted variant features a white icon on a transparent background, suitable for dark backgrounds.

Args: size=50, variant=transparent-inverted, icon=wishlist, oc-aria-label=Icon button of size 50 and variant inverted

<oc-icon-button-v3 icon="wishlist" size="50" variant="transparent-inverted" oc-aria-label="Icon button of size 50 and variant inverted"></oc-icon-button-v3>

Success 100

Story: components-icon-button-variations--icon-button-100-success · tags: components

The success variant uses a green icon on a green background.

Args: size=100, success=true, icon=check, oc-aria-label=Icon button of size 100 and success state

<oc-icon-button-v3 icon="check" size="100" success oc-aria-label="Icon button of size 100 and success state"></oc-icon-button-v3>

Elevation level above

Story: components-icon-button-variations--icon-button-50-elevation-level-above · tags: components

Variation of the default configuration with an elevationLevel of above, adding a moderate shadow to the icon button.

Args: size=50, elevation-level=above, icon=wishlist, oc-aria-label=Icon button of size 50 with elevation-level above

<oc-icon-button-v3 icon="wishlist" size="50" elevation-level="above" oc-aria-label="Icon button of size 50 with elevation-level above"></oc-icon-button-v3>

Elevation level sticky

Story: components-icon-button-variations--icon-button-50-elevation-level-sticky · tags: components

Variation of the default configuration with an elevationLevel of sticky, adding a pronounced shadow to the icon button.

Args: size=50, elevation-level=sticky, icon=wishlist, oc-aria-label=Icon button of size 50 with elevation-level sticky

<oc-icon-button-v3 icon="wishlist" size="50" elevation-level="sticky" oc-aria-label="Icon button of size 50 with elevation-level sticky"></oc-icon-button-v3>

Disabled

Story: components-icon-button-variations--icon-button-50-disabled · tags: components

Variation of the default configuration with the disabled state enabled, preventing user interaction.

Args: size=50, disabled=true, icon=wishlist, oc-aria-label=Icon button of size 50 and variant disabled

<oc-icon-button-v3 icon="wishlist" size="50" disabled oc-aria-label="Icon button of size 50 and variant disabled"></oc-icon-button-v3>

Loading

Story: components-icon-button-variations--icon-button-loading · tags: components

Variation of the default configuration with the loading state enabled, showing a loading animation for the current process.

Args: size=50, icon=wishlist, oc-aria-label=Icon button with an animated loading spinner, loading=true

<oc-icon-button-v3 icon="wishlist" size="50" oc-aria-label="Icon button with an animated loading spinner" loading></oc-icon-button-v3>

Custom icon color

Story: components-icon-button-variations--icon-button-50-custom-icon-color · tags: components

Variation of the default configuration with a custom icon color set via the --icon-color CSS variable.

Args: variant=custom-color-soft, size=50, icon=otto-logo, oc-aria-label=Icon button example with the OTTO logo and a custom set icon color, --background-color=var(--oc-semantic-color-background-above), --icon-color=var(--oc-semantic-color-brand)

<oc-icon-button-v3 icon="otto-logo" variant="custom-color-soft" size="50" oc-aria-label="Icon button example with the OTTO logo and a custom set icon color" style="--background-color: var(--oc-semantic-color-background-above); --icon-color: var(--oc-semantic-color-brand)"></oc-icon-button-v3>

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

The icon button component as a link. Search engines will detect the href.

Args: icon=otto-logo, defaultSlot=<!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#' aria-label='Link icon button'></a>

<oc-icon-button-v3 icon="otto-logo">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#' aria-label='Link icon button'></a>
</oc-icon-button-v3>

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

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

Args: icon=otto-logo, base64-href=Iw==, oc-aria-label=Masked link icon button

<oc-icon-button-v3 icon="otto-logo" base64-href="Iw==" oc-aria-label="Masked link icon button"></oc-icon-button-v3>

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

The icon button 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=(see snippet)

<oc-icon-button-v3 icon="wishlist" base64-href="Iz92YXJpYW50PWZvbw==">
  <!--Search engines will detect the href, while users receive the Base64-encoded version.--><a href='#' aria-label='Icon Button'></a>
</oc-icon-button-v3>

Demo: wishlist

Story: components-icon-button-variations--demo-wishlist · tags: components

<oc-icon-button-v3
  variant="custom-color-soft"
  icon="wishlist"
  oc-aria-label="Add to wishlist"
  style="--background-color: var(--oc-semantic-color-background-above);"
></oc-icon-button-v3>
<script>
  (() => {
    const iconButton = document.getElementsByTagName("oc-icon-button-v3")[0];
    iconButton.addEventListener("click", () => {
      iconButton.selected = !iconButton.selected;
      iconButton.icon = iconButton.selected ? "wishlist-active" : "wishlist";
      iconButton.iconColor = iconButton.selected
        ? "var(--oc-semantic-color-brand)"
        : "var(--oc-semantic-color-text-default)";
      iconButton.ocAriaLabel = iconButton.selected
        ? "Remove from wishlist"
        : "Add to wishlist";
    });
  })();
</script>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: wishlist",
  render() {
    return html`
      <oc-icon-button-v3
        variant="custom-color-soft"
        icon="wishlist"
        oc-aria-label="Add to wishlist"
        style="--background-color: var(--oc-semantic-color-background-above);"
      ></oc-icon-button-v3>
      <script>
        (() => {
          const iconButton = document.getElementsByTagName("oc-icon-button-v3")[0];
          iconButton.addEventListener("click", () => {
            iconButton.selected = !iconButton.selected;
            iconButton.icon = iconButton.selected ? "wishlist-active" : "wishlist";
            iconButton.iconColor = iconButton.selected
              ? "var(--oc-semantic-color-brand)"
              : "var(--oc-semantic-color-text-default)";
            iconButton.ocAriaLabel = iconButton.selected
              ? "Remove from wishlist"
              : "Add to wishlist";
          });
        })();
      </script>
    `;
  }
}

Demo: wishlist with animation

Story: components-icon-button-variations--demo-wishlist-with-animation · tags: components

Demonstration of the icon button with animated icon

<oc-icon-button-v3
  variant="custom-color-soft"
  icon="wishlist"
  oc-aria-label="Add to wishlist"
  style="--background-color: var(--oc-semantic-color-background-above);"
></oc-icon-button-v3>
<script>
  (() => {
    const iconButton = document.getElementsByTagName("oc-icon-button-v3")[0];
    const iconName = "animated-wishlist-active-highlight";
    iconButton.addEventListener("click", () => {
      if (iconButton.getAttribute("icon") === iconName) {
        iconButton.setAttribute("style", "--icon-color:initial");
        iconButton.setAttribute("icon", "wishlist");
      } else {
        iconButton.setAttribute(
          "style",
          "--icon-color:var(--oc-semantic-color-background-brand)",
        );
        iconButton.setAttribute("icon", iconName);
      }
    });
  })();
</script>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: wishlist with animation",
  render() {
    return html`
      <oc-icon-button-v3
        variant="custom-color-soft"
        icon="wishlist"
        oc-aria-label="Add to wishlist"
        style="--background-color: var(--oc-semantic-color-background-above);"
      ></oc-icon-button-v3>
      <script>
        (() => {
          const iconButton = document.getElementsByTagName("oc-icon-button-v3")[0];
          const iconName = "animated-wishlist-active-highlight";
          iconButton.addEventListener("click", () => {
            if (iconButton.getAttribute("icon") === iconName) {
              iconButton.setAttribute("style", "--icon-color:initial");
              iconButton.setAttribute("icon", "wishlist");
            } else {
              iconButton.setAttribute(
                "style",
                "--icon-color:var(--oc-semantic-color-background-brand)",
              );
              iconButton.setAttribute("icon", iconName);
            }
          });
        })();
      </script>
    `;
  }
}

Demo: custom background color

Story: components-icon-button-variations--demo-custom-background-color · tags: components

Demonstration of the icon button with a custom background color set via the --background-color CSS variable.

Args: size=100, variant=custom-color-soft, icon=wishlist, oc-aria-label=Icon button of size 100 with custom background color, --background-color=#FFCCE2

<oc-icon-button-v3 icon="wishlist" size="100" variant="custom-color-soft" oc-aria-label="Icon button of size 100 with custom background color" style="--background-color: #FFCCE2"></oc-icon-button-v3>

Demo: custom background color and icon color

Story: components-icon-button-variations--demo-custom-background-color-icon-color · tags: components

Demonstration of the icon button with a custom background color and icon color set via CSS variables.

Args: size=100, variant=custom-color-strong, icon=speech-bubble-sparkles, --icon-color=#FFFFFF, oc-aria-label=Icon button of size 100 with custom background color, --background-color=#374BC8

<oc-icon-button-v3 icon="speech-bubble-sparkles" size="100" variant="custom-color-strong" oc-aria-label="Icon button of size 100 with custom background color" style="--icon-color: #FFFFFF; --background-color: #374BC8"></oc-icon-button-v3>

Demo: label tooltip

Story: components-icon-button-variations--demo-label-tooltip · tags: components

Demonstration of the icon button with a label tooltip.

Args: size=100, variant=custom-color-strong, icon=info, --icon-color=#FFFFFF, oc-aria-label=Icon button of size 100 with custom background color, --background-color=#374BC8, label=This is a tooltip label

<oc-icon-button-v3 icon="info" size="100" variant="custom-color-strong" oc-aria-label="Icon button of size 100 with custom background color" label="This is a tooltip label" style="--icon-color: #FFFFFF; --background-color: #374BC8"></oc-icon-button-v3>

Demo: elevation levels

Story: components-icon-button-variations--demo-elevation-levels · tags: components

<style>
  .icon-button-grid {
    display: grid;
    grid-template-columns: repeat(4, max-content);
    gap: 32px 48px;
    align-items: center;
    margin: 32px 0;
  }
  .icon-button-grid-header {
    text-align: left;
  }
  .icon-button-grid-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
  }
</style>
<div class="icon-button-grid">
  <div class="icon-button-grid-header"></div>
  <div class="icon-button-grid-header"></div>
  <div class="icon-button-grid-header oc-text-color-sale">above</div>
  <div class="icon-button-grid-header oc-text-color-sale">sticky</div>

  <div class="icon-button-grid-header oc-text-color-sale">secondary-over-color</div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="secondary-over-color"
      elevation-level="canvas"
      oc-aria-label="secondary-over-color canvas"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="secondary-over-color"
      elevation-level="above"
      oc-aria-label="secondary-over-color above"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="secondary-over-color"
      elevation-level="sticky"
      oc-aria-label="secondary-over-color sticky"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-header oc-text-color-sale">primary</div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="primary"
      elevation-level="canvas"
      oc-aria-label="primary canvas"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="primary"
      elevation-level="above"
      oc-aria-label="primary above"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="primary"
      elevation-level="sticky"
      oc-aria-label="primary sticky"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-header oc-text-color-sale">secondary</div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="secondary"
      elevation-level="canvas"
      oc-aria-label="secondary canvas"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="secondary"
      elevation-level="above"
      oc-aria-label="secondary above"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="secondary"
      elevation-level="sticky"
      oc-aria-label="secondary sticky"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-header oc-text-color-sale">tertiary</div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="tertiary"
      oc-aria-label="tertiary canvas"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">n.a.</div>
  <div class="icon-button-grid-cell">n.a.</div>
  <div class="icon-button-grid-header oc-text-color-sale">transparent</div>
  <div class="icon-button-grid-cell">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="transparent"
      oc-aria-label="transparent canvas"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">n.a.</div>
  <div class="icon-button-grid-cell">n.a.</div>
  <div class="icon-button-grid-header oc-text-color-sale">transparent-inverted</div>
  <div class="icon-button-grid-cell" style="background: #212121;">
    <oc-icon-button-v3
      icon="wishlist"
      size="100"
      variant="transparent-inverted"
      oc-aria-label="transparent-inverted canvas"
    ></oc-icon-button-v3>
  </div>
  <div class="icon-button-grid-cell">n.a.</div>
  <div class="icon-button-grid-cell">n.a.</div>
</div>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: elevation levels",
  render() {
    return html`
      <style>
        .icon-button-grid {
          display: grid;
          grid-template-columns: repeat(4, max-content);
          gap: 32px 48px;
          align-items: center;
          margin: 32px 0;
        }
        .icon-button-grid-header {
          text-align: left;
        }
        .icon-button-grid-cell {
          display: flex;
          flex-direction: column;
          align-items: center;
          gap: 16px;
        }
      </style>
      <div class="icon-button-grid">
        <div class="icon-button-grid-header"></div>
        <div class="icon-button-grid-header"></div>
        <div class="icon-button-grid-header oc-text-color-sale">above</div>
        <div class="icon-button-grid-header oc-text-color-sale">sticky</div>

        <div class="icon-button-grid-header oc-text-color-sale">secondary-over-color</div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="secondary-over-color"
            elevation-level="canvas"
            oc-aria-label="secondary-over-color canvas"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="secondary-over-color"
            elevation-level="above"
            oc-aria-label="secondary-over-color above"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="secondary-over-color"
            elevation-level="sticky"
            oc-aria-label="secondary-over-color sticky"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-header oc-text-color-sale">primary</div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="primary"
            elevation-level="canvas"
            oc-aria-label="primary canvas"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="primary"
            elevation-level="above"
            oc-aria-label="primary above"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="primary"
            elevation-level="sticky"
            oc-aria-label="primary sticky"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-header oc-text-color-sale">secondary</div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="secondary"
            elevation-level="canvas"
            oc-aria-label="secondary canvas"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="secondary"
            elevation-level="above"
            oc-aria-label="secondary above"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="secondary"
            elevation-level="sticky"
            oc-aria-label="secondary sticky"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-header oc-text-color-sale">tertiary</div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="tertiary"
            oc-aria-label="tertiary canvas"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">n.a.</div>
        <div class="icon-button-grid-cell">n.a.</div>
        <div class="icon-button-grid-header oc-text-color-sale">transparent</div>
        <div class="icon-button-grid-cell">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="transparent"
            oc-aria-label="transparent canvas"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">n.a.</div>
        <div class="icon-button-grid-cell">n.a.</div>
        <div class="icon-button-grid-header oc-text-color-sale">transparent-inverted</div>
        <div class="icon-button-grid-cell" style="background: #212121;">
          <oc-icon-button-v3
            icon="wishlist"
            size="100"
            variant="transparent-inverted"
            oc-aria-label="transparent-inverted canvas"
          ></oc-icon-button-v3>
        </div>
        <div class="icon-button-grid-cell">n.a.</div>
        <div class="icon-button-grid-cell">n.a.</div>
      </div>
    `;
  }
}

Interaction tests (IconButtonV3.interactions.stories.ts)

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

Fire Interact Event

Story: components-icon-button-interaction-tests--fire-interact-event · tags: play-fn

<oc-icon-button-v3
  icon="wishlist"
  oc-aria-label="Icon button to test event firing"
></oc-icon-button-v3>
Story source (TypeScript, verbatim from Storybook)
{
  render: () => {
    return html` <oc-icon-button-v3
      icon="wishlist"
      oc-aria-label="Icon button to test event firing"
    ></oc-icon-button-v3>`;
  },
  play: async ({
    canvasElement
  }) => {
    const button = canvasElement.getElementsByTagName("oc-icon-button-v3").item(0)!;
    let interacted = 0;
    button.addEventListener("click", () => {
      interacted += 1;
    });
    await expect(interacted).toBe(0);
    await userEvent.click(button);
    await expect(interacted).toBe(1);
  }
}

Show Loading Spinner On Click

Story: components-icon-button-interaction-tests--show-loading-spinner-on-click · tags: play-fn

<oc-icon-button-v3
  icon="wishlist"
  oc-aria-label="Icon button to test the loading state"
></oc-icon-button-v3>
Story source (TypeScript, verbatim from Storybook)
{
  parameters: {
    // Disables Chromatic's snapshotting, as the spinner is animated und thus leads to diffs
    chromatic: {
      disableSnapshot: true
    }
  },
  render: () => {
    return html` <oc-icon-button-v3
      icon="wishlist"
      oc-aria-label="Icon button to test the loading state"
    ></oc-icon-button-v3>`;
  },
  play: async ({
    canvasElement
  }) => {
    const ocbutton = canvasElement.getElementsByTagName("oc-icon-button-v3").item(0)!;
    const button = getByShadowRole(canvasElement, "button");
    await userEvent.click(button);
    ocbutton.loading = true;
    await tick();
    const spinner = Array.from(button.childNodes).find(node => node.nodeName === "OC-SPINNER-V1");
    await expect(spinner).toBeTruthy();
    await expect(ocbutton.loading).toBe(true);
  }
}

V1 (v1, deprecated, not for generation)

Source: ./src/components/icon-button/v1/Overview.mdx

Icon Button v1

Important

This is a deprecated version of the icon button component. For the latest version, see the updated component documentation. Refer to this migration guide to update your project to the latest version.

Default variation

Story Default:

<oc-icon-button-v1 icon-type="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v1>

Configuration

The icon button is highly 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 and see the changes affect the component in real-time.

Usage guidelines

Before integrating the Icon Button 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.

Layout considerations

This component has an extended hitbox. The touch area extends beyond its bounding box, so it may be activated when the user clicks or taps outside the visible component area. Ensure sufficient margin around the component to prevent unintended interactions with adjacent elements.

Accessibility

ARIA label

The icon button component should provide an accessible name with the context or action of the icon button. Therefore is it necessary to set the oc-aria-label attribute in order to make the icon button accessible for assistive technology.

Further reading

V1/Configuration (v1, deprecated, not for generation)

Source: ./src/components/icon-button/v1/Configuration.mdx

Icon Button configuration

Configure the Icon Button 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.

Story Default:

<oc-icon-button-v1 icon-type="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v1>

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

V1/Interaction tests (IconButtonV1.interactions.stories.ts)

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

Fire Interact Event

Story: components-icon-button-v1-interaction-tests--fire-interact-event · tags: play-fn

<oc-icon-button-v1
  icon-type="wishlist"
  oc-aria-label="Icon button to test event firing"
></oc-icon-button-v1>
Story source (TypeScript, verbatim from Storybook)
{
  render: () => {
    return html` <oc-icon-button-v1
      icon-type="wishlist"
      oc-aria-label="Icon button to test event firing"
    ></oc-icon-button-v1>`;
  },
  play: async ({
    canvasElement
  }) => {
    const button = canvasElement.getElementsByTagName("oc-icon-button-v1").item(0)!;
    let interacted = 0;
    button.addEventListener("click", () => {
      interacted += 1;
    });
    await expect(interacted).toBe(0);
    await userEvent.click(button);
    await expect(interacted).toBe(1);
  }
}

Show Loading Spinner On Click

Story: components-icon-button-v1-interaction-tests--show-loading-spinner-on-click · tags: play-fn

<oc-icon-button-v1
  icon-type="wishlist"
  oc-aria-label="Icon button to test the loading state"
></oc-icon-button-v1>
Story source (TypeScript, verbatim from Storybook)
{
  parameters: {
    // Disables Chromatic's snapshotting, as the spinner is animated und thus leads to diffs
    chromatic: {
      disableSnapshot: true
    }
  },
  render: () => {
    return html` <oc-icon-button-v1
      icon-type="wishlist"
      oc-aria-label="Icon button to test the loading state"
    ></oc-icon-button-v1>`;
  },
  play: async ({
    canvasElement
  }) => {
    const ocbutton = canvasElement.getElementsByTagName("oc-icon-button-v1").item(0)!;
    const button = getByShadowRole(canvasElement, "button");
    await new Promise(res => {
      setTimeout(res, 1000);
    });
    await userEvent.click(button);
    ocbutton.loading = true;
    await new Promise(res => {
      setTimeout(res, 1000);
    });
    const spinner = Array.from(button.childNodes).find(node => node.nodeName === "OC-SPINNER-V1");
    await expect(spinner).toBeTruthy();
    await expect(ocbutton.loading).toBe(true);
  }
}

Should Handle Base 64 Href

Story: components-icon-button-v1-interaction-tests--should-handle-base-64-href · tags: play-fn

<oc-icon-button-v1
  icon-type="wishlist"
  oc-aria-label="Icon button to test base64-href handling"
  base64-href="L2Zvbw=="
></oc-icon-button-v1>
Story source (TypeScript, verbatim from Storybook)
{
  render() {
    return html`<oc-icon-button-v1
      icon-type="wishlist"
      oc-aria-label="Icon button to test base64-href handling"
      base64-href="L2Zvbw=="
    ></oc-icon-button-v1>`;
  },
  async play({
    canvasElement
  }) {
    const ocIconButton = canvasElement.getElementsByTagName("oc-icon-button-v1").item(0)!;
    ocIconButton.focus();
    await tick();

    // instead of the div element there should now be an anchor element
    const linkElement = ocIconButton.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(ocIconButton.href).toBe(`${window.location.origin}/foo`);
    await expect(linkElement.href).toBe(`${window.location.origin}/foo`);
  }
}

V1/Variations (v1, deprecated, not for generation)

Source: ./src/components/icon-button/v1/Variations.mdx

Variations

Listed below are the most common variations of the Icon Button 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-icon-button-v1-variations--default · tags: components, icon-button, v1, variations

The default configuration uses the icon-type=wishlist and size=50.

Args: oc-aria-label=Default icon button component

<oc-icon-button-v1 icon-type="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v1>

Transparent

Story: components-icon-button-v1-variations--icon-button-50-transparent · tags: components, icon-button, v1, variations

The transparent variant uses no background color for the icon button.

Args: size=50, variant=transparent, icon-type=wishlist, oc-aria-label=Icon button of size 50 and variant transparent

<oc-icon-button-v1 icon-type="wishlist" size="50" variant="transparent" oc-aria-label="Icon button of size 50 and variant transparent"></oc-icon-button-v1>

Inverted

Story: components-icon-button-v1-variations--icon-button-50-inverted · tags: components, icon-button, v1, variations

The inverted variant features a white icon on a transparent background, suitable for dark backgrounds.

Args: size=50, variant=inverted, icon-type=wishlist, oc-aria-label=Icon button of size 50 and variant inverted

<oc-icon-button-v1 icon-type="wishlist" size="50" variant="inverted" oc-aria-label="Icon button of size 50 and variant inverted"></oc-icon-button-v1>

Elevation 100

Story: components-icon-button-v1-variations--icon-button-50-elevation-100 · tags: components, icon-button, v1, variations

Variation of the default configuration with an elevation of 100, adding a slight shadow to the icon button.

Args: size=50, elevation=100, icon-type=wishlist, oc-aria-label=Icon button of size 50 with elevation 100

<oc-icon-button-v1 icon-type="wishlist" size="50" elevation="100" oc-aria-label="Icon button of size 50 with elevation 100"></oc-icon-button-v1>

Elevation 200

Story: components-icon-button-v1-variations--icon-button-50-elevation-200 · tags: components, icon-button, v1, variations

Variation of the default configuration with an elevation of 100, adding a moderate shadow to the icon button.

Args: size=50, elevation=200, icon-type=wishlist, oc-aria-label=Icon button of size 50 with elevation 200

<oc-icon-button-v1 icon-type="wishlist" size="50" elevation="200" oc-aria-label="Icon button of size 50 with elevation 200"></oc-icon-button-v1>

Elevation 300

Story: components-icon-button-v1-variations--icon-button-50-elevation-300 · tags: components, icon-button, v1, variations

Variation of the default configuration with an elevation of 100, adding a pronounced shadow to the icon button.

Args: size=50, elevation=300, icon-type=wishlist, oc-aria-label=Icon button of size 50 with elevation 300

<oc-icon-button-v1 icon-type="wishlist" size="50" elevation="300" oc-aria-label="Icon button of size 50 with elevation 300"></oc-icon-button-v1>

Disabled

Story: components-icon-button-v1-variations--icon-button-50-disabled · tags: components, icon-button, v1, variations

Variation of the default configuration with the disabled state enabled, preventing user interaction.

Args: size=50, disabled=true, icon-type=wishlist, oc-aria-label=Icon button of size 50 and variant disabled

<oc-icon-button-v1 icon-type="wishlist" size="50" disabled oc-aria-label="Icon button of size 50 and variant disabled"></oc-icon-button-v1>

Loading

Story: components-icon-button-v1-variations--icon-button-loading · tags: components, icon-button, v1, variations

Variation of the default configuration with the loading state enabled, showing a loading animation for the current process.

Args: size=50, icon-type=wishlist, oc-aria-label=Icon button with an animated loading spinner, loading=true

<oc-icon-button-v1 icon-type="wishlist" size="50" oc-aria-label="Icon button with an animated loading spinner" loading></oc-icon-button-v1>

Custom icon color

Story: components-icon-button-v1-variations--icon-button-50-custom-icon-color · tags: components, icon-button, v1, variations

Variation of the default configuration with a custom icon color.

Args: size=50, icon-type=otto-logo, oc-aria-label=Icon button example with the OTTO logo and a custom set icon color, icon-color=var(--oc-semantic-color-brand)

<oc-icon-button-v1 icon-type="otto-logo" size="50" oc-aria-label="Icon button example with the OTTO logo and a custom set icon color" icon-color="var(--oc-semantic-color-brand)"></oc-icon-button-v1>

V2 (v2, deprecated, not for generation)

Source: ./src/components/icon-button/v2/Overview.mdx

Icon button v2

Important

This is a deprecated version of the icon button component. For the latest version, see the updated component documentation. Refer to this migration guide to update your project to the latest version.

The icon button component provides an interactive icon on a circular white background, with attributes for setting the icon, size, ARIA label, a disabled state and emitting a click event when interacted with.

Default variation

Story Default:

<oc-icon-button-v2 icon="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v2>

Configuration

The icon button 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 and see the changes affect the component in real-time.

Usage guidelines

Before integrating the icon button 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 Icon button UX documentation for detailed user experience guidelines.

Layout considerations

This component has an extended hitbox. The touch area extends beyond its bounding box, so it may be activated when the user clicks or taps outside the visible component area. Ensure sufficient margin around the component to prevent unintended interactions with adjacent elements.

Accessibility

The icon button 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 icon button 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.

Further reading

V2/Configuration (v2, deprecated, not for generation)

Source: ./src/components/icon-button/v2/ConfigurationV2.mdx

Icon button configuration

Configure the icon button 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.

Story Default:

<oc-icon-button-v2 icon="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v2>

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

V2/Interaction tests (IconButtonV2.interactions.stories.ts)

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

Fire Interact Event

Story: components-icon-button-v2-interaction-tests--fire-interact-event · tags: play-fn

<oc-icon-button-v2
  icon="wishlist"
  oc-aria-label="Icon button to test event firing"
></oc-icon-button-v2>
Story source (TypeScript, verbatim from Storybook)
{
  render: () => {
    return html` <oc-icon-button-v2
      icon="wishlist"
      oc-aria-label="Icon button to test event firing"
    ></oc-icon-button-v2>`;
  },
  play: async ({
    canvasElement
  }) => {
    const button = canvasElement.getElementsByTagName("oc-icon-button-v2").item(0)!;
    let interacted = 0;
    button.addEventListener("click", () => {
      interacted += 1;
    });
    await expect(interacted).toBe(0);
    await userEvent.click(button);
    await expect(interacted).toBe(1);
  }
}

Show Loading Spinner On Click

Story: components-icon-button-v2-interaction-tests--show-loading-spinner-on-click · tags: play-fn

<oc-icon-button-v2
  icon="wishlist"
  oc-aria-label="Icon button to test the loading state"
></oc-icon-button-v2>
Story source (TypeScript, verbatim from Storybook)
{
  parameters: {
    // Disables Chromatic's snapshotting, as the spinner is animated und thus leads to diffs
    chromatic: {
      disableSnapshot: true
    }
  },
  render: () => {
    return html` <oc-icon-button-v2
      icon="wishlist"
      oc-aria-label="Icon button to test the loading state"
    ></oc-icon-button-v2>`;
  },
  play: async ({
    canvasElement
  }) => {
    const ocbutton = canvasElement.getElementsByTagName("oc-icon-button-v2").item(0)!;
    const button = getByShadowRole(canvasElement, "button");
    await userEvent.click(button);
    ocbutton.loading = true;
    await tick();
    const spinner = Array.from(button.childNodes).find(node => node.nodeName === "OC-SPINNER-V1");
    await expect(spinner).toBeTruthy();
    await expect(ocbutton.loading).toBe(true);
  }
}

Should Handle Base 64 Href

Story: components-icon-button-v2-interaction-tests--should-handle-base-64-href · tags: play-fn

<oc-icon-button-v2
  icon="wishlist"
  oc-aria-label="Icon button to test base64-href handling"
  base64-href="L2Zvbw=="
></oc-icon-button-v2>
Story source (TypeScript, verbatim from Storybook)
{
  render() {
    return html`<oc-icon-button-v2
      icon="wishlist"
      oc-aria-label="Icon button to test base64-href handling"
      base64-href="L2Zvbw=="
    ></oc-icon-button-v2>`;
  },
  async play({
    canvasElement
  }) {
    const ocIconButton = canvasElement.getElementsByTagName("oc-icon-button-v2").item(0)!;
    ocIconButton.focus();
    await tick();

    // instead of the div element there should now be an anchor element
    const linkElement = ocIconButton.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(ocIconButton.href).toBe(`${window.location.origin}/foo`);
    await expect(linkElement.href).toBe(`${window.location.origin}/foo`);
  }
}

V2/Migration (v2, deprecated, not for generation)

Source: ./src/components/icon-button/v2/Migration.mdx

Migration from Icon Button v1 to v2

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

Skip to:

What's new

Elevation system

The new elevation attribute provides more granular control over the button's elevation level with values 100, 200, and 300.

API changes

Removed attributes
v1 Attribute v2 Equivalent Notes
elevated elevation="200" Changed to granular elevation system
transparent variant="transparent" Renamed to variant
variant="inverted" variant="inverted-transparent" Renamed for clarity
icon-type="wishlist" icon="wishlist" Shortened attribute name

How to migrate

The oc-icon-button-v2 removes the deprecated properties elevated and transparent. Additionally, it renames the variant inverted to inverted-transparent, and the property icon-type to icon.

Migrate a basic icon button
<!-- From: -->
<oc-icon-button-v1 icon-type="wishlist" elevated></oc-icon-button-v1>
<!-- To: -->
<oc-icon-button-v2 icon="wishlist" elevation="200"></oc-icon-button-v2>
Migrate a transparent icon button
<!-- From: -->
<oc-icon-button-v1 icon-type="close" transparent></oc-icon-button-v1>
<!-- To: -->
<oc-icon-button-v2 icon="close" variant="transparent"></oc-icon-button-v2>

V2/Variations (v2, deprecated, not for generation)

Source: ./src/components/icon-button/v2/Variations.mdx

Variations

Listed below are the most common variations of the icon button 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-icon-button-v2-variations--default · tags: components

The default configuration uses the icon=wishlist and size=50.

Args: oc-aria-label=Default icon button component

<oc-icon-button-v2 icon="wishlist" oc-aria-label="Default icon button component"></oc-icon-button-v2>

Transparent

Story: components-icon-button-v2-variations--icon-button-50-transparent · tags: components

The transparent variant uses no background color for the icon button.

Args: size=50, variant=transparent, icon=wishlist, oc-aria-label=Icon button of size 50 and variant transparent

<oc-icon-button-v2 icon="wishlist" size="50" variant="transparent" oc-aria-label="Icon button of size 50 and variant transparent"></oc-icon-button-v2>

Inverted transparent

Story: components-icon-button-v2-variations--icon-button-50-inverted-transparent · tags: components

The inverted-transparent variant features a white icon on a transparent background, suitable for dark backgrounds.

Args: size=50, variant=inverted-transparent, icon=wishlist, oc-aria-label=Icon button of size 50 and variant inverted-transparent

<oc-icon-button-v2 icon="wishlist" size="50" variant="inverted-transparent" oc-aria-label="Icon button of size 50 and variant inverted-transparent"></oc-icon-button-v2>

Elevation 100

Story: components-icon-button-v2-variations--icon-button-50-elevation-100 · tags: components

Variation of the default configuration with an elevation of 100, adding a slight shadow to the icon button.

Args: size=50, elevation=100, icon=wishlist, oc-aria-label=Icon button of size 50 with elevation 100

<oc-icon-button-v2 icon="wishlist" size="50" elevation="100" oc-aria-label="Icon button of size 50 with elevation 100"></oc-icon-button-v2>

Elevation 200

Story: components-icon-button-v2-variations--icon-button-50-elevation-200 · tags: components

Variation of the default configuration with an elevation of 100, adding a moderate shadow to the icon button.

Args: size=50, elevation=200, icon=wishlist, oc-aria-label=Icon button of size 50 with elevation 200

<oc-icon-button-v2 icon="wishlist" size="50" elevation="200" oc-aria-label="Icon button of size 50 with elevation 200"></oc-icon-button-v2>

Elevation 300

Story: components-icon-button-v2-variations--icon-button-50-elevation-300 · tags: components

Variation of the default configuration with an elevation of 100, adding a pronounced shadow to the icon button.

Args: size=50, elevation=300, icon=wishlist, oc-aria-label=Icon button of size 50 with elevation 300

<oc-icon-button-v2 icon="wishlist" size="50" elevation="300" oc-aria-label="Icon button of size 50 with elevation 300"></oc-icon-button-v2>

Disabled

Story: components-icon-button-v2-variations--icon-button-50-disabled · tags: components

Variation of the default configuration with the disabled state enabled, preventing user interaction.

Args: size=50, disabled=true, icon=wishlist, oc-aria-label=Icon button of size 50 and variant disabled

<oc-icon-button-v2 icon="wishlist" size="50" disabled oc-aria-label="Icon button of size 50 and variant disabled"></oc-icon-button-v2>

Loading

Story: components-icon-button-v2-variations--icon-button-loading · tags: components

Variation of the default configuration with the loading state enabled, showing a loading animation for the current process.

Args: size=50, icon=wishlist, oc-aria-label=Icon button with an animated loading spinner, loading=true

<oc-icon-button-v2 icon="wishlist" size="50" oc-aria-label="Icon button with an animated loading spinner" loading></oc-icon-button-v2>

Custom icon color

Story: components-icon-button-v2-variations--icon-button-50-custom-icon-color · tags: components

Variation of the default configuration with a custom icon color.

Args: size=50, icon=otto-logo, oc-aria-label=Icon button example with the OTTO logo and a custom set icon color, icon-color=var(--oc-semantic-color-brand)

<oc-icon-button-v2 icon="otto-logo" size="50" oc-aria-label="Icon button example with the OTTO logo and a custom set icon color" icon-color="var(--oc-semantic-color-brand)"></oc-icon-button-v2>

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

The icon button component as a link. Search engines will detect the href.

Args: icon=otto-logo, defaultSlot=<!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#' aria-label='Link icon button'></a>

<oc-icon-button-v2 icon="otto-logo">
  <!--The <a> tag should be placed inside the light DOM to improve SEO.--><a href='#' aria-label='Link icon button'></a>
</oc-icon-button-v2>

Story: components-icon-button-v2-variations--with-masked-link-behavior · tags: components

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

Args: icon=otto-logo, base64-href=Iw==, oc-aria-label=Masked link icon button

<oc-icon-button-v2 icon="otto-logo" base64-href="Iw==" oc-aria-label="Masked link icon button"></oc-icon-button-v2>

Story: components-icon-button-v2-variations--with-link-switch-behavior · tags: components

The icon button 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=(see snippet)

<oc-icon-button-v2 icon="wishlist" base64-href="Iz92YXJpYW50PWZvbw==">
  <!--Search engines will detect the href, while users receive the Base64-encoded version.--><a href='#' aria-label='Icon Button'></a>
</oc-icon-button-v2>

Demo: Wishlist

Story: components-icon-button-v2-variations--demo-wishlist · tags: components

<oc-icon-button-v2 icon="wishlist" oc-aria-label="Add to wishlist"></oc-icon-button-v2>
<script>
  (() => {
    const iconButton = document.getElementsByTagName("oc-icon-button-v2")[0];
    iconButton.addEventListener("click", () => {
      iconButton.selected = !iconButton.selected;
      iconButton.icon = iconButton.selected ? "wishlist-active" : "wishlist";
      iconButton.iconColor = iconButton.selected ? "var(--oc-semantic-color-brand)" : "unset";
      iconButton.ocAriaLabel = iconButton.selected
        ? "Remove from wishlist"
        : "Add to wishlist";
    });
  })();
</script>
Story source (TypeScript, verbatim from Storybook)
{
  name: "Demo: Wishlist",
  render() {
    return html`
      <oc-icon-button-v2 icon="wishlist" oc-aria-label="Add to wishlist"></oc-icon-button-v2>
      <script>
        (() => {
          const iconButton = document.getElementsByTagName("oc-icon-button-v2")[0];
          iconButton.addEventListener("click", () => {
            iconButton.selected = !iconButton.selected;
            iconButton.icon = iconButton.selected ? "wishlist-active" : "wishlist";
            iconButton.iconColor = iconButton.selected ? "var(--oc-semantic-color-brand)" : "unset";
            iconButton.ocAriaLabel = iconButton.selected
              ? "Remove from wishlist"
              : "Add to wishlist";
          });
        })();
      </script>
    `;
  }
}