Can this requirement fit in some design pattern for JS

Let’s assume a UI where currently we show students details on tiles. One tile per student. Now we need to refactor our code to support a new requirement. The new requirement is to change the order of those tiles based on different kind of sorting like – sort by student’s names, sort by student’s grades, sort by their age etc. Here, the sorting criteria will be selected by user on the run time through UI & user should be able to change the sorting criteria whenever he requires.
Right now, we have a list of objects containing student data which contains the required information to show on the tiles. We don’t put any logic on changing the order of tiles & show them in the same order we get it from some other service. To change the order of tiles, I would need to change the order of those objects accordingly because we render tiles on the basis of order of those objects.
Summarizing the requirements –
• User should be able to sort on the basis of different criteria on the run time. Several sorting criteria will be shown to the user.
• User should be able to switch to any sorting criteria or go back to unsorted state at any time.
• Sorting criteria can be many in future. There is no limit to that.
• All this to be implemented in JS.
I am considering this optimization as well–
• Since user can go to any state on his will, I don’t want to call our sorting framework when user is selecting same sorting criteria multiple times. It should be called for the first time only & later if he comes back to same sorting criteria, we shouldn’t be calling our framework again for giving us the sorted order. Instead we should store it somewhere on the first time & keep on using it later on. Eg. - Let say we rendered the tiles in unsorted order. User selects “sort by age” option. We call our framework & show the reordered tiles on the basis of its output. Now user selects some other sort criteria let say “sort by grade” & we call our framework again & reorder tiles based on that. Now user again selects “sort by age” option. Now we shouldn’t be calling our sort framework to sort on the basis of this criteria again to give us the results. Instead we should have saved this data somewhere in the first place so that it can be reused.

Sorting framework is also being created at the same time & is owned by us only. So, we have flexibility to decide the type of inputs & outputs to the framework. However regarding the sorting logic & design, let’s consider it a black box since there I have already decided to go with decorator pattern.
But looks like code changes on the feature side is going to be messy since possibilities for new sorting requirements is endless & we have to maintain the object states of each for reusability. I am brainstorming on several questions like
• How & Where to store the “sort criteria” to its corresponding data which is going to be the input of the sorting framework. Eg. – Let say I want to sort on the basis of age. I would need to get this data & make a map of “sorting criteria to age” for each student. So, I would create a “Map<Student, Map <SortCritria, respectiveData> > This is straightforward approach but can there be any cleaner approach since sort criteria can be many. Also, the big question is where should this logic be placed
• What should be the output of sorting framework. Should it return <oldIndex to newIndex> map or <uniqueStudentId to newIndex > map or anything else.
• Should I introduce a new layer between (eg. Store) our feature & sorting framework or
• should object states be stored in framework or in the feature code base. Etc.
I am looking for a clean approach or a design pattern where all these requirements can fit in. Any suggestions would be greatly appreciated.