-
Notifications
You must be signed in to change notification settings - Fork 714
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10212 from MisRob/coach-accessibility
Coach accessibility improvements
- Loading branch information
Showing
23 changed files
with
1,124 additions
and
787 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
kolibri/plugins/coach/assets/src/composables/useCoachTabs.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/** | ||
* Provides a place to store last tabs interaction | ||
* and helper methods to save and retrieve it. | ||
* This information is typically used to find out | ||
* if a tab was clicked recently so that we can decide | ||
* on whether we should programatically re-focus it after | ||
* navigating to a page. | ||
* | ||
* Motivation: Our routing architecture where parts of a page | ||
* containing tabs get reloaded on route change would result | ||
* in losing focus from the active tab. Therefore, we need | ||
* to programatically re-focus after components are mounted again. | ||
* However, for that we need to be able to estimate when navigation | ||
* occured as a result of user interaction with tabs because in other | ||
* cases focus shouldn't be manipulated (e.g. when visiting a page for | ||
* the first time before clicking on tabs) . | ||
* | ||
* Usage: When tabs are clicked, save that interaction by calling `saveTabsClick`. | ||
* Then when you need find out if tabs were clicked recently, | ||
* call `wereTabsClickedRecently`. | ||
*/ | ||
import { reactive } from 'kolibri.lib.vueCompositionApi'; | ||
|
||
// tabs interaction is considered to be recent | ||
// when it's not older than ... | ||
const RECENT_INTERACTION_LIMIT_IN_MS = 3000; | ||
const TabsEvents = { | ||
CLICK: 'click', | ||
}; | ||
|
||
/** | ||
* Needs to be placed outside of the `useCoachTabs` | ||
* function so that it behaves like global state. | ||
* Why: Due to our routing structure, tab components are re-mounted | ||
* after a tab is clicked. Without placing this state outside, it would | ||
* be lost as components that use this composable are initialized again. | ||
*/ | ||
const lastTabsInteraction = reactive({ | ||
tabsInterfaceId: '', | ||
event: '', | ||
timestamp: '', | ||
}); | ||
|
||
export function useCoachTabs() { | ||
/** | ||
* Stores an interaction with tabs | ||
* | ||
* @param {String} tabsInterfaceId ID of a tabbed interface interacted with | ||
* @param {String} event An event kind. Available kinds: 'click' | ||
*/ | ||
function saveTabsInteraction(tabsInterfaceId, event) { | ||
lastTabsInteraction.tabsInterfaceId = tabsInterfaceId; | ||
lastTabsInteraction.event = event; | ||
lastTabsInteraction.timestamp = Date.now(); | ||
} | ||
|
||
/** | ||
* Stores a click interaction with tabs | ||
* | ||
* @param {String} tabsInterfaceId ID of a tabbed interface interacted with | ||
*/ | ||
function saveTabsClick(tabsInterfaceId) { | ||
saveTabsInteraction(tabsInterfaceId, TabsEvents.CLICK); | ||
} | ||
|
||
/** | ||
* @param {String} tabsInterfaceId ID of a tabbed interface | ||
* @returns {Boolean} `true` when tabs with the provided ID were | ||
* clicked recently | ||
*/ | ||
function wereTabsClickedRecently(tabsInterfaceId) { | ||
if (lastTabsInteraction.tabsInterfaceId !== tabsInterfaceId) { | ||
return false; | ||
} | ||
const diff = Math.abs(Date.now() - lastTabsInteraction.timestamp); | ||
return diff < RECENT_INTERACTION_LIMIT_IN_MS; | ||
} | ||
|
||
return { | ||
saveTabsClick, | ||
wereTabsClickedRecently, | ||
}; | ||
} |
21 changes: 21 additions & 0 deletions
21
kolibri/plugins/coach/assets/src/constants/tabsConstants.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
export const REPORTS_TABS_ID = 'coachReports'; | ||
export const ReportsTabs = { | ||
LESSONS: 'tabLessons', | ||
QUIZZES: 'tabQuizzes', | ||
GROUPS: 'tabGroups', | ||
LEARNERS: 'tabLearners', | ||
}; | ||
|
||
export const PLAN_TABS_ID = 'coachPlan'; | ||
export const PlanTabs = { | ||
LESSONS: 'tabLessons', | ||
QUIZZES: 'tabQuizzes', | ||
GROUPS: 'tabGroups', | ||
}; | ||
|
||
export const REPORTS_GROUP_TABS_ID = 'coachPlanGroup'; | ||
export const ReportsGroupTabs = { | ||
REPORTS: 'tabReports', | ||
MEMBERS: 'tabMembers', | ||
ACTIVITY: 'tabActivity', | ||
}; |
Oops, something went wrong.