Anchor Design System

Accordion2.0

Accordion display a list of high-level options that can expand/collapse to reveal more information.

Installation

npm i @tryg/ui-library

Usage

You wrap your accordion-items in the accordion and it will handle only keeping one item at a time open.

Individual only imports the desired component, and only needs to be included once within the application. Which is beneficial to keep the application size small.

Webcomponent
  <script type="module">
    import { defineCustomElement as defineAccordionElement } from '@tryg/ui-library/dist/components/anchor-accordion';
    import { defineCustomElement as defineAccordionItemElement } from '@tryg/ui-library/dist/components/anchor-accordion-item';
    defineAccordionElement();
    defineAccordionItemElement();
  </script>
  <anchor-accordion>
    <anchor-accordion-item label="First accordion-item">
      <p>Hello world</p>
    </anchor-accordion-item>
    <anchor-accordion-item label="Second accordion-item">
      <p>
        Chislic doner rump bresaola tail alcatra. Short ribs leberkas picanha, salami meatloaf drumstick cupim kielbasa. T-bone landjaeger pancetta drumstick cow ham biltong, cupim
        kielbasa. Ground round shank pork loin, ribeye salami landjaeger drumstick beef turducken bacon corned beef. Turducken boudin ham prosciutto. Andouille shankle t-bone rump
        landjaeger corned beef boudin pork chop pig tri-tip. Prosciutto biltong hamburger, doner capicola corned beef shankle pork loin pork.
      </p>
    </anchor-accordion-item>
  </anchor-accordion>

Global only needs to be defined once in the application, but it will import all components even the ones that are not in use..

Webcomponent
  <script type="module">
    import { defineCustomElements } from '@tryg/ui-library/dist/loader';
    defineCustomElements();
  </script>
  <anchor-accordion>
    <anchor-accordion-item label="First accordion-item">
      <p>Hello world</p>
    </anchor-accordion-item>
    <anchor-accordion-item label="Second accordion-item">
      <p>
        Chislic doner rump bresaola tail alcatra. Short ribs leberkas picanha, salami meatloaf drumstick cupim kielbasa. T-bone landjaeger pancetta drumstick cow ham biltong, cupim
        kielbasa. Ground round shank pork loin, ribeye salami landjaeger drumstick beef turducken bacon corned beef. Turducken boudin ham prosciutto. Andouille shankle t-bone rump
        landjaeger corned beef boudin pork chop pig tri-tip. Prosciutto biltong hamburger, doner capicola corned beef shankle pork loin pork.
      </p>
    </anchor-accordion-item>
  </anchor-accordion>

Expand multiple items

If you set the keep-open prop, then the Accordion will allow multiple items to be expanded at the same time.

Webcomponent
<anchor-accordion style="width:100%;" keep-open>
  <anchor-accordion-item label="First accordion-item">
    <p>Hello world</p>
  </anchor-accordion-item>
  <anchor-accordion-item label="Second accordion-item">
    <p>
      Chislic doner rump bresaola tail alcatra. Short ribs leberkas picanha, salami meatloaf drumstick cupim kielbasa. T-bone landjaeger pancetta drumstick cow ham biltong, cupim
      kielbasa. Ground round shank pork loin, ribeye salami landjaeger drumstick beef turducken bacon corned beef. Turducken boudin ham prosciutto. Andouille shankle t-bone rump
      landjaeger corned beef boudin pork chop pig tri-tip. Prosciutto biltong hamburger, doner capicola corned beef shankle pork loin pork.
    </p>
  </anchor-accordion-item>
</anchor-accordion>

Variants

Accordion has 2 variants: default, and box.

Webcomponent
<anchor-accordion keep-open>
  <anchor-accordion-item label="First accordion-item">
    <p>Hello world</p>
  </anchor-accordion-item>
  <anchor-accordion-item label="Second accordion-item">
    <p>
      Chislic doner rump bresaola tail alcatra. Short ribs leberkas picanha, salami meatloaf drumstick cupim kielbasa. T-bone landjaeger pancetta drumstick cow ham biltong, cupim
      kielbasa. Ground round shank pork loin, ribeye salami landjaeger drumstick beef turducken bacon corned beef. Turducken boudin ham prosciutto. Andouille shankle t-bone rump
      landjaeger corned beef boudin pork chop pig tri-tip. Prosciutto biltong hamburger, doner capicola corned beef shankle pork loin pork.
    </p>
  </anchor-accordion-item>
</anchor-accordion>

Box variant

Webcomponent
<anchor-accordion keep-open>
  <anchor-accordion-item label="First accordion-item">
    <p>Hello world</p>
  </anchor-accordion-item>
  <anchor-accordion-item label="Second accordion-item">
    <p>
      Chislic doner rump bresaola tail alcatra. Short ribs leberkas picanha, salami meatloaf drumstick cupim kielbasa. T-bone landjaeger pancetta drumstick cow ham biltong, cupim
      kielbasa. Ground round shank pork loin, ribeye salami landjaeger drumstick beef turducken bacon corned beef. Turducken boudin ham prosciutto. Andouille shankle t-bone rump
      landjaeger corned beef boudin pork chop pig tri-tip. Prosciutto biltong hamburger, doner capicola corned beef shankle pork loin pork.
    </p>
  </anchor-accordion-item>
</anchor-accordion>

Start content

If you want to display some content before the accordion items, you can set the label slot.

Webcomponent
<anchor-accordion-item variant="box">
  <div slot="label">
    <h1>This content (including the div with the slot attribute) will replace the label</h1>
  </div>
  Nested content is what will be shown when the accordion-item is expanded.
</anchor-accordion-item>

Custom Indicator / Icon

Accordion items have a property called icon. You can use it to customize the open/close indicator.

Webcomponent
<anchor-accordion-item label="Hello" icon-size="xlarge"> Nested content is what will be shown when the accordion-item is expanded. </anchor-accordion-item>

Accordion Item Slots

  • label: The content before the accordion item.
  • action: The element that indicates the open/close state of the accordion item.
  • content: The accordion item content.

Accessibility

  • Keyboard event support for Space, Enter, Arrow Up, Arrow Down and Home / End keys.
  • Keyboard focus management and cross browser normalization.
  • aria-expanded attribute for the accordion item.
  • aria-controls attribute for the accordion item.

API

anchor-accordion

Properties

PropertyAttributeDescriptionTypeDefault
keepOpenkeep-openbooleanfalse

Built with StencilJS

AccordionItem

This component can expand and contract nested content. If you want to have a regular "Accordion" behaviour where only one item can be expanded at a time you need to insert your AccordionItems inside an Accordion.

See Accordion component for an example of this.

Usage

Basic accordion-item

<anchor-accordion-item label="This is a standard label">
  Nested content is what will be shown when the accordion-item is expanded.
  <p>Markup is supported</p>
  <p>And so is other anchor components</p>
  <anchor-button text="Yay!" variant="primary" color="brand" icon="ChevronRight" icon-placement="right" />
</anchor-accordion-item>

The box variant has a different look which adds a border and some margin below.

<anchor-accordion-item label="This is a standard label" variant="box"> Nested content is what will be shown when the accordion-item is expanded. </anchor-accordion-item>

Starting expanded

You can utilize the isExpanded prop to accomplish this. Either by code or by using the html attribute.

Here is an example where we use the attribute

<anchor-accordion-item label="This is a standard label" is-expanded> I will start expanded </anchor-accordion-item>

Customizing the label

In some cases you might need to customize the label inside the header. This can be accomplished by using the label slot

<anchor-accordion-item variant="box">
  <div slot="label">
    <h1>This content (including the div with the slot attribute) will replace the label</h1>
  </div>
  Nested content is what will be shown when the accordion-item is expanded.
</anchor-accordion-item>

Customizing the chevron

In some cases you might need to change the size and/or stroke of the chevron icon. You can do this by using the iconSize and iconStroke props.

Change the icon size:

<anchor-accordion-item icon-size="xlarge"> Nested content is what will be shown when the accordion-item is expanded. </anchor-accordion-item>

Change the stroke size:

<anchor-accordion-item icon-stroke="1"> Nested content is what will be shown when the accordion-item is expanded. </anchor-accordion-item>

Exposed CSS variables

The accordion-item exposes several CSS variables that allows you to control parts of the design with more nuance.

The exposed variables on shadow-root are:

--padding-size: var(--spacing-x5);
--padding-bottom: var(--padding-vertical);
--padding-horizontal: calc(var(--padding-size) * 2);
--padding-shorthand: var(--padding-top) var(--padding-right) var(--padding-bottom) var(--padding-left);
--padding-vertical: var(--padding-size);
--padding-top: var(--padding-vertical);
--padding-left: var(--padding-horizontal);
--padding-right: var(--padding-horizontal);

The exposed variables on the default slot are (by default set to the same values defined in the shadow-root):

--padding-size
--padding-top
--padding-right
--padding-bottom
--padding-left
--padding-shorthand

Example use of the CSS variables

Inject your desired content in the default slot at the first level using the .content class.4px

<anchor-accordion-item class="my-accordion-item">
  <my-content class="content" />
  <my-content class="content" />
  <my-content class="content" />
</anchor-accordion-item>

Each top level element with the content class applied will the automatically inherit the same padding as is defined in the header of the accordion-item.

Both the accordion-item css variables, and the ones in your desired content is then connected, but can also be overriden seperately:

.my-accordion-item {
  --padding-size: 10px; /* This will effect all the padding, both in .my-accordion-item and .content at lower specificity */
}
.content {
  --padding-shorthand: var(--padding-size) var(--padding-size * 3); /* This will only affect the padding in .content, but at a higher specificity */
}

Example usage of Heading Level

The renders its header using whatever HTML heading tag you choose via the heading-level attribute (e.g. when you set heading-level="3"). Under the hood it looks like:

<anchor-accordion>
  <anchor-accordion-item label="First accordion-item" heading-level="3">
    <p>Hello world</p>
  </anchor-accordion-item>
  <anchor-accordion-item label="Second accordion-item" heading-level="3">
    <p>Hello world. Wassuuuup!</p>
  </anchor-accordion-item>
  <anchor-accordion-item label="Third accordion-item" heading-level="3">
    <p>
      Chislic doner rump bresaola tail alcatra. Short ribs leberkas picanha, salami meatloaf drumstick cupim kielbasa. T-bone landjaeger pancetta drumstick cow ham biltong, cupim
      kielbasa. Ground round shank pork loin, ribeye salami landjaeger drumstick beef turducken bacon corned beef. Turducken boudin ham prosciutto. Andouille shankle t-bone rump
      landjaeger corned beef boudin pork chop pig tri-tip. Prosciutto biltong hamburger, doner capicola corned beef shankle pork loin pork.
    </p>
  </anchor-accordion-item>
</anchor-accordion>

Note

  • HeadingTag will be h1–h6 based on heading-level.
  • Classes: header (base styles) and header--vertical-align-[top|center|bottom]
  • Shadow-DOM part: accordion-header
/* lands inside the component’s shadow DOM */
anchor-accordion-item::part(accordion-header) {
  font-size: var(--s-size-text-default);
  margin: var(--s-size-outline-aura-offset);
  font-weight: var(--s-font-weight-heading-emphasized);
}

Properties

PropertyAttributeDescriptionTypeDefault
headingLevelheading-levelHeading level for the accordion item. This is used to determine the heading tag for the accordion item. If not set, it will default to a div.number0
iconiconIcon to display in the header. Note that the icon will be rotated when accordion-item is expanded."activity" | "airplay" | "alarm" | "alert-circle" | "alert-octagon" | "alert-triangle" | "align-center" | "align-justify" | "align-left" | "align-right" | "anchor" | "aperture" | "archive" | "arrow-down" | "arrow-down-circle" | "arrow-down-left" | "arrow-down-right" | "arrow-left" | "arrow-left-circle" | "arrow-right" | "arrow-right-circle" | "arrow-up" | "arrow-up-circle" | "arrow-up-left" | "arrow-up-right" | "at-sign" | "award" | "band-aid" | "bar-chart" | "bar-chart-2" | "basket" | "battery" | "battery-charging" | "bell" | "bell-off" | "bluetooth" | "bold" | "bonus-tryghedsgruppen" | "book" | "book-open" | "bookmark" | "box" | "briefcase" | "calculator" | "calendar" | "camera" | "camera-off" | "cast" | "check" | "check-circle" | "check-square" | "chevron-down" | "chevron-left" | "chevron-right" | "chevron-up" | "chevrons-down" | "chevrons-left" | "chevrons-right" | "chevrons-up" | "chrome" | "circle" | "clipboard" | "clock" | "cloud" | "cloud-drizzle" | "cloud-lightning" | "cloud-off" | "cloud-rain" | "cloud-snow" | "code" | "codepen" | "codesandbox" | "coffee" | "columns" | "command" | "company" | "compass" | "copy" | "corner-down-left" | "corner-down-right" | "corner-left-down" | "corner-left-up" | "corner-right-down" | "corner-right-up" | "corner-up-left" | "corner-up-right" | "cpu" | "credit-card" | "crop" | "crosshair" | "database" | "delete" | "disc" | "divide" | "divide-circle" | "divide-square" | "dollar-sign" | "download" | "download-cloud" | "dribbble" | "droplet" | "edit" | "edit-2" | "edit-3" | "external-link" | "eye" | "eye-off" | "facebook" | "fast-forward" | "feather" | "figma" | "file" | "file-minus" | "file-pdf" | "file-plus" | "file-text" | "film" | "filter" | "flag" | "folder" | "folder-minus" | "folder-plus" | "framer" | "frown" | "gift" | "git-branch" | "git-commit" | "git-merge" | "git-pull-request" | "github" | "gitlab" | "globe" | "grid" | "hard-drive" | "hash" | "headphones" | "heart" | "help-circle" | "hexagon" | "home" | "image" | "inbox" | "info" | "instagram" | "italic" | "key" | "layers" | "layout" | "life-buoy" | "link" | "link-2" | "linkedin" | "list" | "loader" | "lock" | "log-in" | "log-out" | "mail" | "map" | "map-pin" | "maximize" | "maximize-2" | "megaphone" | "meh" | "menu" | "message-circle" | "message-square" | "mic" | "mic-off" | "minimize" | "minimize-2" | "minus" | "minus-circle" | "minus-square" | "monitor" | "moon" | "more-horizontal" | "more-vertical" | "mouse-pointer" | "move" | "music" | "navigation" | "navigation-2" | "octagon" | "offer" | "package" | "paperclip" | "pause" | "pause-circle" | "pen-tool" | "percent" | "phone" | "phone-call" | "phone-forwarded" | "phone-incoming" | "phone-missed" | "phone-off" | "phone-outgoing" | "pie-chart" | "play" | "play-circle" | "plus" | "plus-circle" | "plus-square" | "pocket" | "power" | "printer" | "radio" | "refresh-ccw" | "refresh-cw" | "repeat" | "rewind" | "rotate-ccw" | "rotate-cw" | "rss" | "save" | "scissors" | "search" | "send" | "server" | "settings" | "share" | "share-2" | "shield" | "shield-off" | "shopping-bag" | "shopping-cart" | "shuffle" | "sidebar" | "skip-back" | "skip-forward" | "slack" | "slash" | "sliders" | "smartphone" | "smile" | "speaker" | "sprout" | "square" | "star" | "star-filled" | "stop-circle" | "storm" | "sun" | "sunrise" | "sunset" | "table" | "tablet" | "tag" | "target" | "terminal" | "thermometer" | "thumbs-down" | "thumbs-up" | "toggle-left" | "toggle-right" | "tool" | "trash" | "trash-2" | "trello" | "trending-down" | "trending-up" | "triangle" | "truck" | "trygfonden" | "tv" | "twitch" | "twitter" | "type" | "umbrella" | "underline" | "unlock" | "upload" | "upload-cloud" | "user" | "user-check" | "user-minus" | "user-plus" | "user-x" | "users" | "video" | "video-off" | "voicemail" | "volume" | "volume-1" | "volume-2" | "volume-x" | "watch" | "wifi" | "wifi-off" | "wind" | "x" | "x-circle" | "x-octagon" | "x-square" | "youtube" | "zap" | "zap-off" | "zoom-in" | "zoom-out"'chevron-down'
iconSizeicon-sizeSize of the chevron."large" | "medium" | "small" | "xlarge" | "xsmall"'medium'
iconStrokeicon-strokeStroke size for the chevron.number2
iconVerticalAlignicon-vertical-alignVertical alignment of the icon"center" | "end" | "start"'center'
isExpandedis-expandedWhether the accordion-item is expandedbooleanfalse
labellabelText to display in the headeranyundefined
reversereverseMake the accordion open up on top, instead of on bottombooleanfalse
tabitab-indextabindex is a reserved name so we use tabi which will apply the tabindex attribute Default value should work fine so don't change this unless you have a really good reason to. Set to -1 to disable tabbing.number0
userControlledContentuser-controlled-contentbooleanfalse
uuiduuidGive this instance of accordion item a custom ID, or keep the default.stringuuidv4()
variantvariantStyle of the accordion-item. You should ideally not mix these if using inside an accordion."box" | "default"'default'

Events

EventDescriptionType
toggledEvent dispatched when accordion-item expands or contracts {querySelector}.addEventListener('toggled', ({detail}) => {console.log('expanded:', detail.value)})CustomEvent<{ value: boolean; }>

Shadow Parts

PartDescription
"accordion-header"

CSS Custom Properties

NameDescription
--accordion-background-colorSet the background color of the accordion item.
--accordion-borderSet the shorthand for the accordion item border.
--accordion-border-colorSet the color of the accordion item border.
--accordion-border-sizeSet the size of the accordion item border.
--accordion-border-styleSet the style of the accordion item border.
--accordion-box-sizingSet the box sizing of the accordion item.
--accordion-chevron-marginDEPRECATED: Use --accordion-chevron-margin-left instead. Kept for backwards compatibility, but will be removed by February 2025
--accordion-chevron-margin-bottomSet the bottom margin on the chevron icon.
--accordion-chevron-margin-leftSet the left margin on the chevron icon.
--accordion-chevron-margin-rightSet the right margin on the chevron icon.
--accordion-chevron-margin-topSet the top margin on the chevron icon.
--accordion-header-gapSet the gap between header elements.
--accordion-padding-bottomSet the size of the bottom padding.
--accordion-padding-horizontalSet the size of the horizontal padding.
--accordion-padding-leftSet the size of the left padding.
--accordion-padding-rightSet the size of the right padding.
--accordion-padding-shorthandSet the shorthand for all padding values.
--accordion-padding-sizeSet the size of the padding around the accordion item.
--accordion-padding-topSet the size of the top padding.
--accordion-padding-verticalSet the size of the vertical padding.
--background-colorDEPRECATED: Use --accordion-background-color instead. Kept for backwards compatibility, but will be removed by April 2024
--borderDEPRECATED: Use --accordion-border instead. Kept for backwards compatibility, but will be removed by April 2024
--border-colorDEPRECATED: Use --accordion-border-color instead. Kept for backwards compatibility, but will be removed by April 2024
--border-sizeDEPRECATED: Use --accordion-border-size instead. Kept for backwards compatibility, but will be removed by April 2024
--border-styleDEPRECATED: Use --accordion-border-style instead. Kept for backwards compatibility, but will be removed by April 2024
--box-sizingDEPRECATED: Use --accordion-box-sizing instead. Kept for backwards compatibility, but will be removed by April 2024
--header-gapDEPRECATED: Use --accordion-header-gap instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-bottomDEPRECATED: Use --accordion-padding-bottom instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-horizontalDEPECATED: Use --accordion-padding-horizontal instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-leftDEPRECATED: Use --accordion-padding-left instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-rightDEPRECATED: Use --accordion-padding-right instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-shorthandDEPRECATED: Use --accordion-padding-shorthand instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-sizeDEPRECATED: Use --accordion-padding-size instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-topDEPRECATED: Use --accordion-padding-top instead. Kept for backwards compatibility, but will be removed by April 2024
--padding-verticalDEPRECATED: Use --accordion-padding-vertical instead. Kept for backwards compatibility, but will be removed by April 2024

Dependencies

Used by

Depends on

Graph


Built with StencilJS

On this page