Contextual Links: Link External

The four variants are:

  • Regular link: icon is sds-icon-arrownext
  • Link external: icon is sds-icon-externallink
  • Modal trigger: icon is sds-icon-infocircleborder
  • Accordion: icon is sds-icon-plus. The icon change happens automatically thanks to the bootstrap accordion JS.

When the contextual link item isn't a link, it's a button, with the following attributes:

  • Modal Trigger: sds-contextualList__action gets the data-toggle="modal" data-target="#modaID" attributes
  • Accordion:
    • sds-contextualList gets an id (contextualListAccordion) that will be used as reference by all collapse elements through their data-parent attribute
    • The sds-contextualList__item gets an id that references the corresponding collapse element's aria-labelledby attribute.
    • sds-contextualList__action gets the data-target="#currentCollapseItemID" aria-controls="currentCollapseItemID" attributes which both reference the collapse tied to sds-contextualList__action
    • The .collapse element gets id="currentCollapseItemID" data-parent="#contextualListAccordion" aria-labelledby="contextualListItem-11"

If you want to have a specific item shown by default, you'll need to set sds-contextualList__action's aria-expanded attribute to true and add the show class to the collapse element by default.

If you're having trouble implementing the accordion variant, check the bootstrap accordion documentation

<ul class="sds-contextualList list-unstyled">

    <li class="sds-contextualList__item">

        <a data-scope-wrapper="box" data-scope="sunken" href="" target="_blank" class="sds-contextualList__action">
            <span class="sds-btn -iconBtn -btnSecondary -btnSmall sds-contextualList__actionIcon" aria-hidden="true">

                <span class="sds-icon sds-icon-externallink"></span>

            </span>
            <span class="sds-contextualList__actionText">Link external</span>
        </a>

    </li>

    <li class="sds-contextualList__item">

        <a data-scope-wrapper="box" data-scope="sunken" href="" target="_blank" class="sds-contextualList__action">
            <span class="sds-btn -iconBtn -btnSecondary -btnSmall sds-contextualList__actionIcon" aria-hidden="true">

                <span class="sds-icon sds-icon-externallink"></span>

            </span>
            <span class="sds-contextualList__actionText">Que faire si je ne connais plus le code PIN de ma carte bancaire ?</span>
        </a>

    </li>

    <li class="sds-contextualList__item">

        <a data-scope-wrapper="box" data-scope="sunken" href="" target="_blank" class="sds-contextualList__action">
            <span class="sds-btn -iconBtn -btnSecondary -btnSmall sds-contextualList__actionIcon" aria-hidden="true">

                <span class="sds-icon sds-icon-externallink"></span>

            </span>
            <span class="sds-contextualList__actionText">Quelle est la limite mensuelle de ma carte de crédit et comment l&#39;augmenter ?</span>
        </a>

    </li>

    <li class="sds-contextualList__item">

        <a data-scope-wrapper="box" data-scope="sunken" href="" target="_blank" class="sds-contextualList__action">
            <span class="sds-btn -iconBtn -btnSecondary -btnSmall sds-contextualList__actionIcon" aria-hidden="true">

                <span class="sds-icon sds-icon-externallink"></span>

            </span>
            <span class="sds-contextualList__actionText">Que faire en cas d’oubli du code secret de ma carte de paiement ?</span>
        </a>

    </li>

    <li class="sds-contextualList__item">

        <a data-scope-wrapper="box" data-scope="sunken" href="" target="_blank" class="sds-contextualList__action">
            <span class="sds-btn -iconBtn -btnSecondary -btnSmall sds-contextualList__actionIcon" aria-hidden="true">

                <span class="sds-icon sds-icon-externallink"></span>

            </span>
            <span class="sds-contextualList__actionText">Recommandations en matière de sécurité des cartes de paiements</span>
        </a>

    </li>

</ul>
<ul class="{{ namespace }}contextualList list-unstyled{% for mod in modifiers %} {{ mod }}{% endfor %}{% for mod in classes %} {{ mod }}{% endfor %}"{% if accordion %} id="{{ accordion }}"{% endif %}>
	{% for key, item in items %}
	<li class="{{ namespace }}contextualList__item"{% if accordion %} id="contextualListItem-{{ loop.index }}"{% endif %}>
		{% if accordion or modal %}
			<button type="button"
					data-scope-wrapper="box"
					data-scope="{{ scope or "sunken" }}"
					class="{{ namespace }}contextualList__action"
					{% if modal %} data-toggle="modal" data-target="#{{ modal }}"{% endif %}
					{% if accordion %} data-toggle="collapse" data-target="#contextualListCollapse-{{ loop.index }}" aria-controls="contextualListCollapse-{{ loop.index }}" aria-expanded="{% if item.expanded %}{{ item.expanded }}{% else %}{{ expanded }}{% endif %}"{% endif %}
			>
				{% render "@icon-btn-secondary--small",{
					classes: [namespace + "contextualList__actionIcon"],
					eltType: "span",
					icon: icon,
					attrs: {
						"aria-hidden": "true"
					}
				},true %}
				<span class="{{ namespace }}contextualList__actionText">{{ item.text }}</span>
			</button>
			{% if accordion %}
			<div data-scope-wrapper="box" data-scope="flat" class="{{ namespace }}contextualList__collapse collapse{% if item.expanded === "true" or expanded === "true" %} show{% endif %}" id="contextualListCollapse-{{ loop.index }}" data-parent="#{{ accordion }}" aria-labelledby="contextualListItem-{{ loop.index }}{{ loop.index }}">
				<div class="{{ namespace }}contextualList__collapseInner {{ namespace }}stripContainerPadding">
					<div class="container">
						collapse content
					</div>
				</div>
			</div>
			{% endif %}
		{% else %}
			<a data-scope-wrapper="box" data-scope="{{ scope or "sunken" }}" href="{{ href }}"{% if targetBlank %} target="_blank"{% endif %} class="{{ namespace }}contextualList__action">
				{% render "@icon-btn-secondary--small",{
					classes: [namespace + "contextualList__actionIcon"],
					eltType: "span",
					icon: icon,
					attrs: {
						"aria-hidden": "true"
					}
				},true %}
				<span class="{{ namespace }}contextualList__actionText">{{ item.text }}</span>
			</a>
		{% endif %}
	</li>
	{% endfor %}
</ul>
  • Content:
    /* variables specific to current element */
    
    $contextual-list-collapse-inner-padding: map-deep-get($token-spacer-inset-map, "md");
    $contextual-list-collapse-inner-padding-lg: map-deep-get($token-spacer-inset-map, "lg");
    $contextual-list-action-margin: map-deep-get($token-spacer-inline-map, "sm");
    $contextual-list-action-margin-lg: map-deep-get($token-spacer-inline-map, "md");
    
    .#{$namespace}contextualList {
    
    	/* Save root element context for easy access if nesting is needed */
    
    	$self: &;
    
    	/* properties of current element  + media queries */
    	
    
    	/* Pseudo Elements */
    
    	&::before {
    	}
    
    	&::after {
    	}
    
    	/*
    	Include elements that are linked to the current element but have to reside at the root level of the stylesheet
    	(e.g: keyframes)
    	*/
    	@at-root {
    	}
    
    
    	/* children - write selector in full in comments in order to facilitate search */
    
    	&__item {
    		
    		& + & {
    
    			margin-top: map-deep-get($token-spacer-stack-max-map, "sm");
    
    		}
    		
    	}
    	
    	// contextualList__action
    	&__action {
    
    		// follows same logic as parent
    
    		@include custom-prop-fallback("background-color", "sys-color-elevation-surface-sunken");
    		display: flex;
    		align-items: center;
    		padding: map-deep-get($token-spacer-inset-map, "md");
    		border-radius: map-deep-get($token-radius-map, "16");
    		width: 100%; // for button dimensions
    		text-align: left; // for button text alignment
    		transition: background-color 0.15s linear, border-radius 0.15s linear, box-shadow 0.15s linear;
    
    		@include media-breakpoint-up(lg) {
    			padding: map-deep-get($token-spacer-inset-map, "lg");
    		}
    
    		&[aria-expanded="true"] {
    
    			position: relative;
    			@include custom-prop-fallback("background-color", "sys-color-elevation-surface-flat");
    			z-index: z("low");
    			border-bottom-left-radius: 0;
    			border-bottom-right-radius: 0;
    			box-shadow: 0 (-(map-deep-get($token-sizes-unit-map, "16") - map-deep-get($token-sizes-unit-map, "4"))) map-deep-get($token-sizes-unit-map, "16") 0 rgba(map-deep-get($token-color-brand-map, "secondary", "100"),0.1);
    			transition: background-color 0.15s linear, box-shadow 0.15s linear;
    
    			&:hover,
    			&:focus {
    				@media (hover: hover) {
    
    					@include custom-prop-fallback("background-color", "sys-color-elevation-surface-flat");
    
    					#{$self}__actionIcon {
    
    						@include custom-prop-fallback("background-color", "comp-button-secondary-hovered-background-color");
    
    					}
    
    				}
    
    			}
    
    		}
    
    		&[data-scope="elevated"] {
    
    			&[aria-expanded="true"][aria-expanded="true"] {
    
    				@include custom-prop-fallback("background-color", "comp-accordion-active-background-color");
    
    				#{$self}__actionIcon {
    
    					@include custom-prop-fallback("background-color", "comp-button-secondary-hovered-background-color");
    
    				}
    
    				&:hover,
    				&:focus {
    					@media (hover: hover) {
    
    						#{$self}__actionIcon {
    
    							@include custom-prop-fallback("background-color", "comp-button-secondary-hovered-background-color");
    
    						}
    
    					}
    
    				}
    
    			}
    
    		}
    
    		&[data-scope="flat"] {
    
    			@include custom-prop-fallback("background-color","comp-box-background-color");
    
    		}
    
    		&:hover,
    		&:focus {
    			@media (hover: hover) {
    
    				@include custom-prop-fallback("background-color", "comp-accordion-hovered-background-color");
    
    				#{$self}__actionIcon {
    
    					@include custom-prop-fallback("background-color", "comp-button-secondary-inverse-background-color");
    
    				}
    
    			}
    		}
    
    	}
    
    	// contextualList__actionIcon
    	&__actionIcon {
    
    		margin-right: map-deep-get($token-spacer-inline-map, "sm");
    
    		[aria-expanded="true"] & {
    
    			@include custom-prop-fallback("background-color", "comp-button-secondary-background-color");
    
    			[class*="icon"]::before {
    
    				content: map-deep-get($token-icon-map, "minus")
    
    			}
    
    		}
    
    		@include media-breakpoint-up(lg) {
    			margin-right: map-deep-get($token-spacer-inline-map, "md");
    		}
    
    	}
    
    	&__actionText {
    
    		@extend %headingBase;
    		@extend %h4;
    		@include custom-prop-fallback("color", "comp-accordion-text-color","true","true");
    
    	}
    
    	&__collapse {
    
    		position: relative;
    		box-shadow: map-deep-get($token-shadow-map, "detail");
    		transition: $transition-collapse, box-shadow 0.15s linear;
    		border-bottom-left-radius: map-deep-get($token-radius-map, "16");
    		border-bottom-right-radius: map-deep-get($token-radius-map, "16");
    		@include custom-prop-fallback("background-color", "comp-accordion-active-background-color");
    
    		&.show {
    
    			#{$self}__collapseInner {
    
    				&::before {
    
    					opacity: 1;
    					transition: opacity 0.15s linear;
    				}
    
    			}
    
    		}
    		
    	}
    
    	&__collapseInner {
    
    		position: relative;
    		padding: $contextual-list-collapse-inner-padding;
    		border-radius: inherit;
    
    		@include media-breakpoint-up(lg){
    
    			padding: $contextual-list-collapse-inner-padding-lg;
    			padding-left: $contextual-list-collapse-inner-padding-lg + map-deep-get($token-icon-btn-size-map, "smaller", "width") + $contextual-list-action-margin-lg;
    
    		}
    
    		&::before {
    
    			content: "";
    			position: absolute;
    			opacity: 0;
    			top: 0;
    			left: $contextual-list-collapse-inner-padding;
    			@extend %brandLine;
    
    			transition-delay: 0s;
    			transition-duration: 0s;
    			@include media-breakpoint-up(lg) {
    				left: $contextual-list-collapse-inner-padding-lg + map-deep-get($token-icon-btn-size-map, "smaller", "width") + $contextual-list-action-margin-lg;
    			}
    
    		}
    
    	}
    
    
    	/* modifiers */
    
    	// contextualList -inverted
    	&.-inverted {
    
    		// follows same logic as base element
    
    		#{$self}__action {
    
    			@include custom-prop-fallback("background-color", "sys-color-elevation-surface-flat");
    
    			&[aria-expanded="true"][aria-expanded="true"] {
    
    				@include custom-prop-fallback("background-color", "sys-color-elevation-surface-flat");
    
    				&:hover,
    				&:focus {
    					@media (hover: hover) {
    
    						#{$self}__actionIcon {
    
    							@include custom-prop-fallback("background-color", "comp-button-secondary-hovered-background-color");
    
    						}
    
    					}
    
    				}
    
    			}
    
    			&:hover,
    			&:focus {
    				@media (hover: hover) {
    
    					@include custom-prop-fallback("background-color", "comp-accordion-hovered-background-color");
    
    					#{$self}__actionIcon {
    
    						@include custom-prop-fallback("background-color", "comp-button-secondary-inverse-background-color");
    
    					}
    
    				}
    
    			}
    
    		}
    
    		#{$self}__actionIcon {
    
    			@include custom-prop-fallback("background-color", "comp-button-secondary-background-color");
    
    		}
    
    	}
    
    	/* random parent element */
    	/* 
    	*
    	*   Syntax : .randomParentElt & {}
    	*
    	*/
    
    	/* Pseudo Classes */
    
    	&:hover {
    		@media (hover: hover) {
    
    		}
    	}
    
    	&:focus {
    	}
    
    	&:active {
    	}
    
    	&:focus,
    	&:active {
    	}
    
    }
  • URL: /components/raw/spk-contextual-links/_contextual-links.scss
  • Filesystem Path: components/spuerkeess-site/organisms/contextual-links/_contextual-links.scss
  • Size: 6.5 KB