<div class="border border--rounded margin--x--m padding--m">
<div class="status-indicator" data-status-list="Stap overgeslagen|Stap voltooid|Huidige stap|Toekomstige stap">
<div class="status-indicator__lines">
<span class="status-indicator__background"></span>
<span class="status-indicator__progress"></span>
</div>
<ol class="status-indicator__content">
<li class="status-indicator__step status-indicator__skip-step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Basisinformatie<span>(Stap overgeslagen)</span></button>
</div>
</li>
<li class="status-indicator__step status-indicator__done-step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Aanvullende informatie</button>
</div>
<ol class="status-indicator__description-list">
<li class="status-indicator__description-container">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">
13 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.<br>
</span>
</li>
</ol>
</li>
<li class="status-indicator__step status-indicator__current-step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Intake</button>
<button type="button" class="button button--icon tooltip-trigger" data-placement="top" data-title="De gemeente heeft uw aanvraag van een omgevingsvergunning in behandeling genomen. De gemeente beoordeelt inhoudelijk uw aanvraag.">
<span aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 16 16" class="icon">
<path d="M9.07,4.43A1.3,1.3,0,0,0,7.61,3.07a2.78,2.78,0,0,0-2,1L3.89,2.46A5.5,5.5,0,0,1,8,.5c2.33,0,4.1,1.15,4.1,3.71s-3.25,3.47-3,6H6.34C5.9,7.28,9.07,6.06,9.07,4.43ZM5.81,13.5a1.92,1.92,0,1,1,3.83,0,1.92,1.92,0,1,1-3.83,0Z"></path>
</svg>
</span>
<span class="screen-reader-only">De gemeente heeft uw aanvraag van een omgevingsvergunning in behandeling genomen. De gemeente beoordeelt inhoudelijk uw aanvraag.</span>
</button>
</div>
<ol class="status-indicator__description-list">
<li class="status-indicator__description-container">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">19 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.</span>
</li>
<li class="status-indicator__description-container">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">22 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.</span>
</li>
</ol>
</li>
<li class="status-indicator__step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Samenvatting</button>
</div>
<ol class="status-indicator__description-list">
<li class="status-indicator__description-container" tabindex="-1">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">21 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.</span>
</li>
</ol>
</li>
</ol>
</div>
</div>
<div class="border border--rounded margin--x--m padding--m">
<div class="status-indicator" data-status-list="Stap overgeslagen|Stap voltooid|Huidige stap|Toekomstige stap">
<div class="status-indicator__lines">
<span class="status-indicator__background"></span>
<span class="status-indicator__progress"></span>
</div>
<ol class="status-indicator__content">
<li class="status-indicator__step status-indicator__skip-step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Basisinformatie<span>(Stap overgeslagen)</span></button>
</div>
</li>
<li class="status-indicator__step status-indicator__done-step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Aanvullende informatie</button>
</div>
<ol class="status-indicator__description-list">
<li class="status-indicator__description-container">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">
13 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.<br>
</span>
</li>
</ol>
</li>
<li class="status-indicator__step status-indicator__current-step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Intake</button>
<button type="button" class="button button--icon tooltip-trigger" data-placement="top" data-title="De gemeente heeft uw aanvraag van een omgevingsvergunning in behandeling genomen. De gemeente beoordeelt inhoudelijk uw aanvraag.">
<span aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 16 16" class="icon">
<path d="M9.07,4.43A1.3,1.3,0,0,0,7.61,3.07a2.78,2.78,0,0,0-2,1L3.89,2.46A5.5,5.5,0,0,1,8,.5c2.33,0,4.1,1.15,4.1,3.71s-3.25,3.47-3,6H6.34C5.9,7.28,9.07,6.06,9.07,4.43ZM5.81,13.5a1.92,1.92,0,1,1,3.83,0,1.92,1.92,0,1,1-3.83,0Z"></path>
</svg>
</span>
<span class="screen-reader-only">De gemeente heeft uw aanvraag van een omgevingsvergunning in behandeling genomen. De gemeente beoordeelt inhoudelijk uw aanvraag.</span>
</button>
</div>
<ol class="status-indicator__description-list">
<li class="status-indicator__description-container">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">19 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.</span>
</li>
<li class="status-indicator__description-container">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">22 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.</span>
</li>
</ol>
</li>
<li class="status-indicator__step">
<div class="status-indicator__title-container">
<span class="status-indicator__icon"></span>
<button class="status-indicator__label">Samenvatting</button>
</div>
<ol class="status-indicator__description-list">
<li class="status-indicator__description-container" tabindex="-1">
<span class="status-indicator__dot"></span>
<span class="status-indicator__description">21 maart: Uw aanvraag is in goed orde ontvangen. Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur explicabo nisi officiis tempore totam? Blanditiis dicta.</span>
</li>
</ol>
</li>
</ol>
</div>
</div>
/* No context defined for this component. */
// Component variables
$status-indicator-default-color: $grey-dark;
$status-indicator-mute-color: $grey-light;
$status-indicator-done-color: $blue;
$status-indicator-passed-color: $green;
$status-indicator-background-color: $white;
$status-indicator-bold: $fw-medium;
$status-indicator-line-width: 2px;
$status-indicator-icon-container-width: 24px;
$status-indicator-label-icon-space: $space-xs;
$status-indicator-x-axis-spacing: $space-l;
$status-indicator-icon-width: 16px;
$status-indicator-margin: 1.5px;
$status-indicator-small-text: $fs-down-1;
$status-indicator-first-layer: $layer-status-indicator;
$status-indicator-second-layer: $layer-status-indicator + 1;
$status-indicator-third-layer: $layer-status-indicator + 2;
.status-indicator {
$parent: &;
display: flex;
flex-direction: column;
position: relative;
&__status {
font-weight: $fw-medium;
}
&__lines {
position: absolute;
width: 100%;
height: 100%;
#{$parent}__background,
#{$parent}__progress {
content: '';
position: absolute;
top: math.div($status-indicator-icon-container-width, 2) + $status-indicator-margin;
left: (math.div($status-indicator-icon-container-width, 2) - math.div($status-indicator-line-width, 2));
width: $status-indicator-line-width;
}
#{$parent}__background {
background-color: $status-indicator-mute-color;
z-index: $status-indicator-second-layer;
bottom: math.div($status-indicator-icon-container-width, 2) + $status-indicator-margin;
}
#{$parent}__progress {
background-color: $status-indicator-passed-color;
z-index: $status-indicator-second-layer;
}
}
ol {
padding: 0;
margin: 0;
list-style: none;
}
&__content {
z-index: $status-indicator-second-layer;
}
&__title-container,
&__description-container {
padding-top: $status-indicator-x-axis-spacing;
}
&__title-container {
display: flex;
flex-direction: row;
align-items: center;
color: $status-indicator-mute-color;
#{$parent}__step:first-child & {
padding-top: 0;
}
}
&__icon {
display: flex;
justify-content: center;
align-items: center;
width: $status-indicator-icon-container-width;
height: $status-indicator-icon-container-width;
background-color: $status-indicator-background-color;
border: $status-indicator-line-width solid $status-indicator-mute-color;
border-radius: 50%;
.icon {
width: $status-indicator-icon-width;
height: $status-indicator-icon-width;
}
// Status depending styles.
#{$parent}__done-step &,
#{$parent}__current-step & {
border-color: $status-indicator-passed-color;
color: $status-indicator-passed-color;
}
}
&__description {
margin-left: $status-indicator-label-icon-space;
}
&__label {
display: flex;
align-items: center;
border: none;
margin: 0 0 0 $status-indicator-label-icon-space;
padding: 0;
width: auto;
overflow: visible;
background: transparent;
font-family: $font-sans;
font-size: $fs-base;
line-height: $base-line-height;
-webkit-font-smoothing: inherit;
-moz-osx-font-smoothing: inherit;
-webkit-appearance: none;
&::-moz-focus-inner {
border: 0;
padding: 0;
}
&:focus {
color: $black;
background-color: $yellow;
border-color: $black;
}
#{$parent}__skip-step & span {
font-size: $fs-down-2;
font-weight: $fw-normal;
margin-left: $space-xxs;
}
#{$parent}__current-step &,
#{$parent}__done-step & {
color: $status-indicator-done-color;
text-decoration: underline;
&:hover {
cursor: pointer;
}
}
#{$parent}__open & {
color: $status-indicator-default-color;
font-weight: $status-indicator-bold;
text-decoration: none;
&:hover {
cursor: default;
}
}
}
&__description {
font-size: $status-indicator-small-text;
}
&__description-container {
display: none;
flex-direction: row;
align-items: center;
#{$parent}__open & {
display: flex;
}
}
&__dot {
z-index: $status-indicator-third-layer;
flex-shrink: 0;
background-color: $status-indicator-passed-color;
border: $status-indicator-line-width solid $status-indicator-background-color;
width: ($status-indicator-icon-width - ($status-indicator-line-width * 2));
height: ($status-indicator-icon-width - ($status-indicator-line-width * 2));
border-radius: 50%;
margin: (($status-indicator-icon-container-width - $status-indicator-icon-width) * .5) + $status-indicator-line-width;
}
button + .tooltip-trigger {
margin-left: $space-xxs;
}
}
@media (max-width: $mobile) {
.status-indicator__label {
font-size: $fs-down-1;
}
}
import {
getElementRectPlus,
calculateDistance,
} from '../../../js/utils/dom-geometry';
var STEP_STATUS = {
OPEN: 'OPEN',
CURRENT: 'CURRENT',
DONE: 'DONE',
SKIP: 'SKIP',
};
var circleIcon = '' +
'<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" xml:space="preserve" class="icon" aria-hidden="true" role="presentation" focusable="false">' +
'<g>' +
'<circle fill="currentColor" cx="8" cy="8" r="8"/>' +
'</g>' +
'</svg>';
var checkIcon = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 16 16" class="icon" aria-hidden="true" role="presentation" focusable="false">' +
'<g>' +
'<polygon fill="currentColor" points="16,3.8 14.1,1.8 12,3.9 5.6,10.3 1.9,6.6 0,8.6 3.7,12.2 3.7,12.2 5.6,14.2 7.5,12.2 7.5,12.2"/>' +
'</g>' +
'</svg>';
/**
* Initialize status indicator.
*
* @param {Element} statusIndicatorElement Status indicator DOM element.
*/
export default function StatusIndicator (statusIndicatorElement) {
var component = {
statusIndicatorElement: statusIndicatorElement,
backgroundLineElement: statusIndicatorElement.getElementsByClassName(
'status-indicator__background')[0],
progressLineElement: statusIndicatorElement.getElementsByClassName(
'status-indicator__progress')[0],
allStepsDone: true,
steps: [],
setProgress: setProgress,
statusTextList: parseStepStatusStringToObject(
statusIndicatorElement.dataset.statusList),
};
// Set toggle trigger if exist.
// Why do we need this? If initially the content is hidden
// getBoundingClientRect will return zero, which will also result in step
// center not calculated correctly.
var toggleTriggerElement = null;
if (component.statusIndicatorElement.dataset.toggleTrigger) {
toggleTriggerElement = document.getElementById(
component.statusIndicatorElement.dataset.toggleTrigger);
}
if (toggleTriggerElement) {
toggleTriggerElement.addEventListener('click', function () {
component.setProgress();
});
}
var stepItems = component.statusIndicatorElement.getElementsByClassName(
'status-indicator__step');
for (var stepItemIndex = 0; stepItemIndex <
stepItems.length; stepItemIndex++) {
var stepElement = stepItems[stepItemIndex];
var step = {
element: stepElement,
iconElement: stepElement.getElementsByClassName(
'status-indicator__icon')[0],
labelElement: stepElement.getElementsByClassName(
'status-indicator__label')[0],
status: null,
isLastStep: false,
};
// Toggle step description content.
step.element.addEventListener('click', handleToggle(component));
// Initially set state and icon depending on class name.
if (stepElement.classList.contains('status-indicator__skip-step')) {
step.status = STEP_STATUS.SKIP;
step.iconElement.innerHTML = generateIconElementContent(
component.statusTextList[step.status], checkIcon);
step.labelElement.disabled = true;
} else if (stepElement.classList.contains('status-indicator__done-step')) {
step.status = STEP_STATUS.DONE;
step.iconElement.innerHTML = generateIconElementContent(
component.statusTextList[step.status], checkIcon);
step.labelElement.disabled = false;
} else if (stepElement.classList.contains(
'status-indicator__current-step')) {
step.status = STEP_STATUS.CURRENT;
step.element.classList.add('status-indicator__open');
step.iconElement.innerHTML = generateIconElementContent(
component.statusTextList[step.status], circleIcon);
step.labelElement.disabled = true;
component.allStepsDone = false;
} else {
step.status = STEP_STATUS.OPEN;
step.iconElement.innerHTML = generateIconElementContent(
component.statusTextList[step.status]);
step.labelElement.disabled = true;
}
component.steps[stepItemIndex] = step;
}
// Handle last step
var lastStep = component.steps[component.steps.length - 1];
lastStep.isLastStep = true;
// In case all steps are done, open the last step.
if (component.allStepsDone) {
lastStep.element.classList.add('status-indicator__open');
}
component.setProgress();
// Recalculate progress line on window resize (responsive behaviour).
window.addEventListener('resize', function () {
component.setProgress();
});
}
/**
* Parse the list of step statuses to object.
*
* @param {string} statusesAsString
* @return {{[p: string]: string}}
*/
function parseStepStatusStringToObject (statusesAsString) {
var splitString = statusesAsString.split('|');
return {
'SKIP': splitString[0],
'DONE': splitString[1],
'CURRENT': splitString[2],
'OPEN': splitString[3],
};
}
/**
* Generate content for the step icon element. Depending on the status a screen
* reader text is put in place.
*
* @param {string} statusText
* @param {string} iconSnippet
* @return {string}
*/
function generateIconElementContent (statusText, iconSnippet) {
iconSnippet = (typeof iconSnippet !== 'undefined') ? iconSnippet : '';
return '' +
iconSnippet +
'<span class="screen-reader-only">' + statusText + '</span>';
}
/**
* Handle toggling of title description.
*
* @param {Object} component Status indicator container.
* @returns {EventListener} Click event.
*/
function handleToggle (component) {
return function (event) {
// Don't need to toggle open step.
if (this.classList.contains('status-indicator__open')) {
return;
}
// Steps to come are not togglable.
if (!this.classList.contains('status-indicator__current-step') &&
!this.classList.contains('status-indicator__done-step')) {
return;
}
// Only handle clicks on the title.
if (event.target.classList.contains('status-indicator__label')) {
var currentStepElement = component.statusIndicatorElement.getElementsByClassName(
'status-indicator__open')[0];
// Toggle disabled mode for button.
currentStepElement.getElementsByClassName(
'status-indicator__label')[0].disabled = false;
event.target.disabled = true;
// Toggle open state on step.
currentStepElement.classList.remove('status-indicator__open');
this.classList.toggle('status-indicator__open');
// Recalculate progress line.
component.setProgress();
// Set focus on collapsed content.
this.getElementsByClassName('status-indicator__description')[0].focus();
}
};
}
/**
* Set progress depending on the steps that are already done.
*/
function setProgress () {
var progressHeight = 0;
var backgroundHeight = 0;
var previousStepRectPlus = null;
for (var i = 0; i < this.steps.length; i++) {
var step = this.steps[i];
var currentStepRectPlus = getElementRectPlus(step.iconElement);
var distance = 0;
if (previousStepRectPlus) {
distance = calculateDistance(previousStepRectPlus.center,
currentStepRectPlus.center);
}
backgroundHeight += distance;
if (
step.status === STEP_STATUS.DONE
|| step.status === STEP_STATUS.SKIP
|| step.status === STEP_STATUS.CURRENT
) {
progressHeight += distance;
}
if ((step.status === STEP_STATUS.CURRENT || step.isLastStep) &&
step.element.classList.contains('status-indicator__open')) {
var subStepDotElementList = step.element.querySelectorAll(
'.status-indicator__dot');
var subStepDotElementListRectPlus = getElementRectPlus(
subStepDotElementList[subStepDotElementList.length - 1]);
progressHeight += calculateDistance(currentStepRectPlus.center,
subStepDotElementListRectPlus.center);
}
previousStepRectPlus = currentStepRectPlus;
}
this.progressLineElement.style.height = progressHeight + 'px';
this.backgroundLineElement.style.height = backgroundHeight + 'px';
}
There are no notes for this item.