-isActive and -isOpen are toggled on the main element for styles.
Check the Timer.js file in the assets tab on the right to see how the interaction happens.
The timer should also collapse when one of the items in the .sds-timer__actionMenu is clicked.
<div class="sds-timer -isActive">
<div class="sds-timer__header">
<div class="sds-timer__timeZone">
<button type="button" class="sds-btn -iconBtn -btnSecondary sds-timer__collapseToggle js-timer__collapseToggle" data-toggle="collapse" data-target="#timerCollapse" aria-expanded="false">
<span class="sds-icon sds-icon-chevrondown"></span>
</button>
<div class="sds-timer__title sds-textBodyXl">02:12</div>
<div class="sds-timer__clock">
<div class="sds-timer__title sds-timer__clockTitle sds-textBodyXxl">02:12</div>
<div class="sds-circularProgress sds-timer__circularProgress">
<svg viewBox="0 0 36 36" class="">
<circle class="sds-circularProgress__bgShape" cx="18" cy="18" r="16" stroke="#000" stroke-width="1.5" fill="none" />
<path class="sds-circularProgress__shape" stroke-dasharray="50, 100" d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831" />
</svg>
</div>
</div>
</div>
<div class="sds-timer__timeZoneFooter">
<div class="sds-timer__inactiveGroup">
<button type="button" class="sds-btn -btnPrimary -block sds-timer__btn js-activateTimer">
<span class="sds-btn__text">Déclarer une entrée</span>
</button>
</div>
<div class="sds-timer__activeGroup sds-btnGroup">
<button type="button" class="sds-btn -btnPrimary -block sds-timer__btn js-deactivateTimer">
<span class="sds-btn__text">Déclarer une sortie</span>
</button>
<div class="dropdown">
<button type="button" class="sds-btn -btnSecondary sds-timer__btnSecondary" data-toggle="dropdown" data-target="#timerDropdown" aria-expanded="false" data-reference="parent">
<span class="sds-btn__text">Plus</span>
</button>
<div aria-labelledby="" class="sds-actionMenu dropdown-menu dropdown-menu-right sds-timer__actionMenu">
<a href="" class="sds-actionMenu__item dropdown-item">
Raison sortie 1
</a>
<a href="" class="sds-actionMenu__item dropdown-item">
Raison sortie 2
</a>
<a href="" class="sds-actionMenu__item dropdown-item">
Raison sortie 3
</a>
</div>
</div>
</div>
</div>
</div>
<div class="sds-timer__collapseWrapper">
<div class="sds-timer__collapse collapse" id="timerCollapse">
<div class="sds-timer__timeline">
<div class="sds-timer__timelineHeader">
<div class="h4">Lundi 12 Février 2022</div>
</div>
<div class="sds-timer__timelineBody">
<div class="sds-sectionItemTimeline -startEndDots ">
<div class="sds-sectionItem -isTimelineItem -dotNoWidth -isStatic">
<div class="sds-sectionItem__inner">
<div class="sds-sectionItem__innerCol -date">
<div class="sds-sectionItem__textMeta sds-textHelper">
15h58
</div>
</div>
<div class="sds-sectionItem__innerCol -dot">
<div class="sds-sectionItem__dotWrapper">
<span class="sds-dot -success100"></span>
</div>
</div>
<div class="sds-sectionItem__innerCol -grow">
<div class="sds-stackXxs">
<div>Sortie</div>
</div>
</div>
</div>
</div>
<div class="sds-sectionItem -isTimelineItem -dotNoWidth -isStatic">
<div class="sds-sectionItem__inner">
<div class="sds-sectionItem__innerCol -date">
<div class="sds-sectionItem__textMeta sds-textHelper">
14h05
</div>
</div>
<div class="sds-sectionItem__innerCol -dot">
<div class="sds-sectionItem__dotWrapper">
<span class="sds-dot -success100"></span>
</div>
</div>
<div class="sds-sectionItem__innerCol -grow">
<div class="sds-stackXxs">
<div>Entrée</div>
<div class="sds-sectionItem__textMeta sds-textHelper">Réunion (BIO) - 1, Place de Metz</div>
</div>
</div>
</div>
</div>
<div class="sds-sectionItem -isTimelineItem -dotNoWidth -isStatic">
<div class="sds-sectionItem__inner">
<div class="sds-sectionItem__innerCol -date">
<div class="sds-sectionItem__textMeta sds-textHelper">
12h06
</div>
</div>
<div class="sds-sectionItem__innerCol -dot">
<div class="sds-sectionItem__dotWrapper">
<span class="sds-dot -primary100"></span>
</div>
</div>
<div class="sds-sectionItem__innerCol -grow">
<div class="sds-stackXxs">
<div>Sortie</div>
</div>
</div>
</div>
</div>
<div class="sds-sectionItem -isTimelineItem -dotNoWidth -isStatic">
<div class="sds-sectionItem__inner">
<div class="sds-sectionItem__innerCol -date">
<div class="sds-sectionItem__textMeta sds-textHelper">
07h24
</div>
</div>
<div class="sds-sectionItem__innerCol -dot">
<div class="sds-sectionItem__dotWrapper">
<span class="sds-dot -success100"></span>
</div>
</div>
<div class="sds-sectionItem__innerCol -grow">
<div class="sds-stackXxs">
<div>Entrée</div>
<div class="sds-sectionItem__textMeta sds-textHelper">Réunion - Bâtiment Rousegaertchen</div>
</div>
</div>
</div>
</div>
<div class="sds-sectionTitle -isTimelineItem">
<div class="sds-sectionTitle__inner">
<div class="sds-sectionTitle__col">
<div class="sds-sectionTitle__textMain">
Bonifications & pénalisations
</div>
</div>
</div>
</div>
<div class="sds-sectionItem -isTimelineItem -dotNoWidth -isStatic">
<div class="sds-sectionItem__inner">
<div class="sds-sectionItem__innerCol -date">
<div class="sds-sectionItem__textMeta sds-textHelper">
+01:40
</div>
</div>
<div class="sds-sectionItem__innerCol -dot">
<div class="sds-sectionItem__dotWrapper">
<span class="sds-dot -faded100"></span>
</div>
</div>
<div class="sds-sectionItem__innerCol -grow">
<div class="sds-stackXxs">
<div>Bonification pour visite médicale</div>
</div>
</div>
</div>
</div>
<div class="sds-sectionItem -isTimelineItem -dotNoWidth -isStatic">
<div class="sds-sectionItem__inner">
<div class="sds-sectionItem__innerCol -date">
<div class="sds-sectionItem__textMeta sds-textHelper">
-00:40
</div>
</div>
<div class="sds-sectionItem__innerCol -dot">
<div class="sds-sectionItem__dotWrapper">
<span class="sds-dot -faded100"></span>
</div>
</div>
<div class="sds-sectionItem__innerCol -grow">
<div class="sds-stackXxs">
<div>Retard</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="{{ namespace }}timer{% for mod in modifiers %} {{ mod }}{% endfor %}{% for mod in classes %} {{ mod }}{% endfor %}">
<div class="{{ namespace }}timer__header">
<div class="{{ namespace }}timer__timeZone">
{% render '@icon-btn-secondary',{
icon: "icon-chevrondown",
classes: [namespace+"timer__collapseToggle","js-timer__collapseToggle"],
attrs: {
"data-toggle": "collapse",
"data-target": "#timerCollapse",
"aria-expanded": "false"
}
}, true %}
<div class="{{ namespace }}timer__title {{ namespace }}textBodyXl">{{ time }}</div>
<div class="{{ namespace }}timer__clock">
<div class="{{ namespace }}timer__title {{ namespace }}timer__clockTitle {{ namespace }}textBodyXxl">{{ time }}</div>
{% render "@snet-circular-progress",{
classes: [namespace+"timer__circularProgress"],
circleShapeBg: true
},true %}
</div>
</div>
<div class="{{ namespace }}timer__timeZoneFooter">
<div class="{{ namespace }}timer__inactiveGroup">
{% render '@btn-primary--full-width',{
text: "Déclarer une entrée",
classes: [namespace + "timer__btn", "js-activateTimer"]
}, true %}
</div>
<div class="{{ namespace }}timer__activeGroup {{ namespace }}btnGroup">
{% render '@btn-primary--full-width',{
text: "Déclarer une sortie",
classes: [namespace + "timer__btn", "js-deactivateTimer"]
}, true %}
<div class="dropdown">
{% render '@btn-secondary',{
text: "Plus",
classes: [namespace + "timer__btnSecondary"],
attrs: {
"data-toggle": "dropdown",
"data-target": "#timerDropdown",
"aria-expanded": "false",
"data-reference": "parent"
}
}, true %}
{% render "@snet-action-menu",timerActionMenuOptions,true %}
</div>
</div>
</div>
</div>
<div class="{{ namespace }}timer__collapseWrapper">
<div class="{{ namespace }}timer__collapse collapse" id="timerCollapse">
<div class="{{ namespace }}timer__timeline">
<div class="{{ namespace }}timer__timelineHeader">
<div class="h4">Lundi 12 Février 2022</div>
</div>
<div class="{{ namespace }}timer__timelineBody">
{% render "@snet-status-timeline" %}
</div>
</div>
</div>
</div>
</div>
export default class Timer {
constructor() {
this.addActiveClass();
this.toggleOpenClass();
this.closeOnSortieIfDeployed();
}
addActiveClass () {
let activateBtn = $(".js-activateTimer");
let deactivateBtn = $(".js-deactivateTimer");
activateBtn.on("click", (e) => {
$(e.target).closest(".sds-timer").addClass("-isActive");
});
deactivateBtn.on("click", (e) => {
$(e.target).closest(".sds-timer").removeClass("-isActive");
});
}
toggleOpenClass () {
$("#timerCollapse").on('hide.bs.collapse', function () {
$(".sds-timer").removeClass("-isOpen");
})
$("#timerCollapse").on('show.bs.collapse', function () {
$(".sds-timer").addClass("-isOpen");
})
}
closeOnSortieIfDeployed () {
let deactivateBtn = $(".js-deactivateTimer");
deactivateBtn.on("click", (e) => {
if($(e.target).closest(".sds-timer").hasClass("-isOpen")) {
$("#timerCollapse").collapse("hide");
$(e.target).closest(".sds-timer").removeClass("-isActive");
}
});
}
}
@use "sass:math";
/* variables specific to current element */
$timer-transition-timing: 0.25s;
$timer-base-width: map-deep-get($token-sizes-component-map, "timer", "base-width");
$timer-expanded-width: map-deep-get($token-sizes-component-map, "timer", "expanded-width");
$timer-open-clock-dimensions: map-deep-get($token-sizes-component-map, "timer", "active-clock-dimension");
.#{$namespace}timer {
/* Save root element context for easy access if nesting is needed */
$self: &;
/* properties of current element + media queries */
position: fixed;
z-index: z("sticky");
right: $snet-frame-main-horiz-padding-mobile;
bottom: $snet-frame-main-horiz-padding-mobile;
width: $timer-base-width;
border-radius: map-deep-get($token-radius-map, "16");
@include custom-prop-fallback("background-color", "comp-box-raised-background-color");
box-shadow: $dropdown-box-shadow;
display: flex;
flex-direction: column;
max-height: calc(100% - #{$snet-frame-main-horiz-padding-desktop-global*2} - #{$snet-frame-nav-topbar-height});
overflow: hidden;
transition: width $timer-transition-timing linear;
@include media-breakpoint-up(lg) {
right: $snet-frame-main-horiz-padding-desktop;
bottom: $snet-frame-main-horiz-padding-desktop;
}
/* 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 */
// timer__timeZone
&__timeZone {
display: flex;
align-items: flex-start;
justify-content: space-between;
min-height: 0;
transition: all $timer-transition-timing linear;
position: relative;
}
&__timeZoneFooter {
margin-top: map-deep-get($token-spacer-unit-map, "32");
}
&__title {
margin-top: auto;
@include custom-prop-fallback("color", "sys-color-text-neutral-vivid");
transition: opacity $timer-transition-timing linear;
}
&__activeGroup {
display: none;
}
&__btn {
flex-grow: 1;
}
&__header {
@include spacer-component-inset("md");
}
&__collapseToggle {
position: absolute;
top: 0;
left: 0;
&[aria-expanded="false"] {
* {
&::before {
content: map-deep-get($token-icon-map, "chevronup")
}
}
}
}
&__collapse {
transition: height $timer-transition-timing linear;
}
&__collapseWrapper {
@include custom-prop-fallback("background-color", "comp-box-background-color");
overflow-y: auto;
border-radius: map-deep-get($token-radius-map, "16");
}
&__timeline {
overflow-y: auto;
}
&__timelineHeader {
padding: map-deep-get($token-spacer-unit-map, "32") map-deep-get($token-spacer-unit-map, "16") map-deep-get($token-spacer-unit-map, "24");
border-bottom: 1px solid $border-color;
}
&__timelineBody {
margin-top: -(map-deep-get($token-spacer-unit-map,"4"));
padding-bottom: map-deep-get($token-spacer-unit-map, "16");
}
&__btnSecondary#{$self}__btnSecondary {
@include custom-prop-fallback("background-color", "sys-color-background-primary-100");
@include custom-prop-fallback("color", "sys-color-text-neutral-inverse");
@include hover-focus() {
@include custom-prop-fallback("background-color", "sys-color-background-primary-120", "true", "true");
}
}
&__clock {
width: map-deep-get($token-sizes-unit-map, "96");
height: map-deep-get($token-sizes-unit-map, "96");
transition: all $timer-transition-timing linear;
position: relative;
}
&__clockTitle {
position: absolute;
top: 50%;
left: 50%;
bottom: auto;
transform: translate(-50%,-50%);
visibility: hidden;
opacity: 0;
transition: opacity $timer-transition-timing linear;
}
&__circularProgress {
circle {
@include custom-prop-fallback("stroke", "sys-color-background-primary-20");
}
path {
@include custom-prop-fallback("stroke", "sys-color-background-highlight-100");
stroke-width: 1.5;
}
}
&__actionMenu {
margin: map-deep-get($token-spacer-unit-map, "8") 0;
}
/* modifiers */
// timer -isActive
&.-isActive {
@include gradient-x(map-deep-get($token-color-brand-map, "secondary", "140"), map-deep-get($token-color-brand-map, "secondary", "160"), 40%, 100%);
#{$self}__title {
@include custom-prop-fallback("color", "sys-color-text-neutral-inverse");
}
#{$self}__circularProgress {
circle {
@include custom-prop-fallback("stroke", "sys-color-background-primary-100");
}
path {
stroke-width: 1.5;
}
}
#{$self}__activeGroup {
display: flex;
}
#{$self}__inactiveGroup {
display: none;
}
}
&.-isOpen {
width: $timer-expanded-width;
#{$self}__title {
visibility: hidden;
opacity: 0;
}
#{$self}__clockTitle {
visibility: visible;
opacity: 1;
}
#{$self}__clock {
width: $timer-open-clock-dimensions;
height: $timer-open-clock-dimensions;
transform: translateX(-(math.div($timer-expanded-width, 2) - map-deep-get($token-spacer-unit-map, "16") - (math.div($timer-open-clock-dimensions,2))));
}
}
/* random parent element */
/*
*
* Syntax : .randomParentElt & {}
*
*/
/* Pseudo Classes */
&:hover {
@media (hover: hover) {
}
}
&:focus {
}
&:active {
}
&:focus,
&:active {
}
}