Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion js/PageLevelProgressIndicatorView.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class PageLevelProgressIndicatorView extends Backbone.View {
if (isPresentationComponentWithItems) {
const children = this.model.getChildren();
const visited = children.filter(child => child.get('_isVisited'));
return Math.round(visited.length / children.length * 100);
// Handle division by zero when component has no children
return children.length === 0 ? 0 : Math.round(visited.length / children.length * 100);
}
return 0;
}
Expand Down Expand Up @@ -98,6 +99,8 @@ class PageLevelProgressIndicatorView extends Backbone.View {
const data = this.model.toJSON();
data.ariaLabel = this.ariaLabel;
data.type = this.type;
data._globals = Adapt.course.get('_globals');
data._isOptional = this.model.get('_isOptional') || false;
return data;
}

Expand Down
3 changes: 2 additions & 1 deletion js/completionCalculations.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ class Completion extends Backbone.Controller {
// this allows the user to see if assessments have been passed, if assessment components can be retaken, and all other component's completion
const completed = completionObject.nonAssessmentCompleted + completionObject.assessmentCompleted + completionObject.subProgressCompleted;
const total = completionObject.nonAssessmentTotal + completionObject.assessmentTotal + completionObject.subProgressTotal;
const percentageComplete = Math.floor((completed / total) * 100);
// Handle division by zero when page contains only optional content
const percentageComplete = total === 0 ? 0 : Math.floor((completed / total) * 100);
return percentageComplete;
}

Expand Down
21 changes: 19 additions & 2 deletions less/pageLevelProgressIndicator.less
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
// Global indicator
// --------------------------------------------------
.pagelevelprogress {
&__indicator-outer {
display: flex;
flex-direction: column;
align-items: flex-start;
}

&__indicator-group {
display: flex;
flex-direction: column;
align-items: center;
}

&__indicator {
display: flex;
width: 2rem;
Expand Down Expand Up @@ -28,7 +40,12 @@
width: var(--adapt-pagelevelprogress-percentage);
}

&__indicator .js-indicator-aria-label {
top: 0;
&__indicator-label {
font-size: 0.5rem;
font-weight: normal;
text-align: center;
margin-top: 0.125rem;
line-height: 1;
white-space: nowrap;
}
}
35 changes: 33 additions & 2 deletions templates/pageLevelProgressIndicator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,40 @@ import { compile } from 'core/js/reactHelpers';

export default function PageLevelProgressIndicator (props) {
const {
ariaLabel
ariaLabel,
_isOptional
} = props;

// Build aria-label with optional prefix if needed
const compiledAriaLabel = ariaLabel ? compile(ariaLabel, props) : '';
const optionalLabel = props._globals?._accessibility?._ariaLabels?.optional || 'Optional';
const fullAriaLabel = _isOptional ? `${optionalLabel}. ${compiledAriaLabel}` : compiledAriaLabel;

// Only render wrapper group when optional label exists
if (_isOptional) {
return (
<span className='pagelevelprogress__indicator-group'>
<span className='pagelevelprogress__indicator'>
<span className="pagelevelprogress__indicator-inner">

<span className="pagelevelprogress__indicator-bar"></span>

{ariaLabel &&
<span className="aria-label">
{fullAriaLabel}
</span>
}

</span>
</span>

<span className="pagelevelprogress__indicator-label" aria-hidden="true">
{optionalLabel}
</span>
</span>
);
}

return (
<span className='pagelevelprogress__indicator'>
<span className="pagelevelprogress__indicator-inner">
Expand All @@ -14,7 +45,7 @@ export default function PageLevelProgressIndicator (props) {

{ariaLabel &&
<span className="aria-label">
{compile(ariaLabel, props)}
{fullAriaLabel}
</span>
}

Expand Down