Heheh. This is a surprisingly hard problem, to emulate file system selection behavior. I enjoyed this one myself :)
Not really angular-specific, but it's fun. As far as I know nobody has written a lib for it. It's tough to isolate a selection model from UI and data dependencies, so you're probably on your own to build it.
Here's how I solved it (as I recall).
1: Click by itself deselects everything, then selects whatever you clicked, unless it was selected, then it deselects this. Subtle difference from...
2: CTRL click toggles. This is easy.
3: Either click or CTRL click sets a "lastSingleClick" variable. This is your anchor for the shift click.
4: Shift click selects from your "lastSingleClick" until the clicked index. Your selection model knows the full set of selections, but you need to separately store "currentSpanSelection"s, because...
5: Every time you shift click, the first thing you do is deselect everything in "currentSpanSelections", because the behavior file systems show is spans fipping around if you change what you shift+click on.
So the total set of selection data you need for this algo is:
* currentSpan = [] // array of the most recent shift selected span
* lastSingleClick = 3 // the index of the last single click that happened, naked or CTRL.
* selections = [] // all of the selections