Skip to content

Commit ba4d0f4

Browse files
committed
make the context properties more semantic #21
1 parent 53bc1a7 commit ba4d0f4

13 files changed

+284
-279
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# macos-multi-select
22

3-
Given a list of ids, and an action, return a list of selected items with the same behaviour of macOS finder list view selection.
3+
Given an Index, and an Action, return an array of selected keys with the same behaviour of macOS finder list view selection.
44

55
🌟 [List of Features Known](documentation/features.md)

documentation/features.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
# Toggle Key Selection
3737

3838
## Scenarios
39-
### Should be able to add and remove a selection one item in a non empty index
39+
### Should be able to add and remove a selection one key in a non empty index
4040

4141
| | |
4242
| --- | ---|
@@ -133,7 +133,7 @@
133133

134134
# Select Next
135135
# Scenarios
136-
### Should do nothing if no items
136+
### Should do nothing if no keys
137137
| | |
138138
| --- | ---|
139139
| Implemented ||
@@ -151,7 +151,7 @@
151151

152152
![demo](./images/select_next_key_scenario_2.gif)
153153

154-
### Should never select beyond last item
154+
### Should never select beyond last key
155155

156156
| | |
157157
| --- | ---|
@@ -202,7 +202,7 @@
202202
| Hot Key | `Arrow Up` |
203203

204204
![demo](./images/select_previous_key_scenario_2.gif)
205-
### Should never select beyond first item
205+
### Should never select beyond first key
206206

207207
| | |
208208
| --- | ---|

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "macos-multi-select",
3-
"version": "0.1.9",
4-
"description": "Given a list of ids, and an action, return a list of selected items with the same behaviour of macOS finder list view selection.",
3+
"version": "0.2.0-rc.0",
4+
"description": "Given an Index, and an Action, return an array of selected keys with the same behaviour of macOS finder list view selection.",
55
"main": "dist/index.js",
66
"repository": "[email protected]:codingedgar/macos-multi-select.git",
77
"author": "codingedgar <[email protected]>",

src/arrayUtils.ts

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,61 @@
11
import { head } from "ramda";
22

33
export function findNextPivot(
4-
sortedArray: string[],
4+
sortedIndex: string[],
55
subarray: string[],
66
previousPivot: string
77
): string {
8-
const previousIndex = sortedArray.indexOf(previousPivot);
9-
let nextIndex = previousIndex + 1;
8+
const previous = sortedIndex.indexOf(previousPivot);
9+
let next = previous + 1;
1010

11-
while (nextIndex <= sortedArray.length - 1) {
12-
const nextItem = sortedArray[nextIndex];
13-
if (subarray.includes(nextItem)){
14-
return nextItem;
11+
while (next <= sortedIndex.length - 1) {
12+
const nextKey = sortedIndex[next];
13+
if (subarray.includes(nextKey)){
14+
return nextKey;
1515
};
16-
nextIndex++;
16+
next++;
1717
}
1818

19-
nextIndex = previousIndex - 1;
19+
next = previous - 1;
2020

21-
while (nextIndex >= 0) {
22-
const prevItem = sortedArray[nextIndex];
23-
if (subarray.includes(prevItem)) {
24-
return prevItem;
21+
while (next >= 0) {
22+
const prevKey = sortedIndex[next];
23+
if (subarray.includes(prevKey)) {
24+
return prevKey;
2525
}
26-
nextIndex--;
26+
next--;
2727
}
2828

29-
return head(sortedArray)!
29+
return head(sortedIndex)!
3030
}
3131

3232
export function findAdjacentToPivotInSortedArray(
33-
sortedArray: string[],
33+
sortedIndex: string[],
3434
subarray: string[],
35-
item: string
35+
key: string
3636
): string[] {
37-
const indexOfItem = sortedArray.indexOf(item);
38-
let leftIndex = indexOfItem;
39-
let rightIndex = indexOfItem;
37+
const indexOfKey = sortedIndex.indexOf(key);
38+
let leftIndex = indexOfKey;
39+
let rightIndex = indexOfKey;
4040
let hasLeftAdjacent = leftIndex > 0;
41-
let hasRightAdjacent = rightIndex < sortedArray.length - 1;
41+
let hasRightAdjacent = rightIndex < sortedIndex.length - 1;
4242
while ((hasLeftAdjacent || hasRightAdjacent)) {
4343
if (leftIndex > 0) {
44-
const nextLeft = sortedArray[leftIndex - 1];
44+
const nextLeft = sortedIndex[leftIndex - 1];
4545
hasLeftAdjacent = subarray.includes(nextLeft);
4646
leftIndex = hasLeftAdjacent ? leftIndex - 1 : leftIndex;
4747
} else {
4848
hasLeftAdjacent = false
4949
}
5050

51-
if (rightIndex < sortedArray.length - 1) {
52-
const nextRight = sortedArray[rightIndex + 1];
51+
if (rightIndex < sortedIndex.length - 1) {
52+
const nextRight = sortedIndex[rightIndex + 1];
5353
hasRightAdjacent = subarray.includes(nextRight);
5454
rightIndex = hasRightAdjacent ? rightIndex + 1 : rightIndex;
5555
} else {
5656
hasRightAdjacent = false
5757
}
5858
}
5959

60-
return sortedArray.slice(leftIndex, rightIndex + 1);
60+
return sortedIndex.slice(leftIndex, rightIndex + 1);
6161
}

src/index.ts

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { difference, head, last, take, union, without } from "ramda";
1+
import { head, last, take, union, without } from "ramda";
22
import { findAdjacentToPivotInSortedArray, findNextPivot } from "./arrayUtils";
33

44
export type Context = {
5-
list: string[],
5+
index: string[],
66
selected: string[],
77
adjacentPivotstring | undefined,
88
}
@@ -15,15 +15,15 @@ export type Command =
1515
| { type: "SELECT NEXT" }
1616
| { type: "SELECT PREVIOUS" }
1717

18-
function listIncludesAndIsNotEmpty(list: string[], item: string) {
19-
return list.length > 0 && list.includes(item)
18+
function listIncludesAndIsNotEmpty(index: string[], key: string) {
19+
return index.length > 0 && index.includes(key)
2020
}
2121

2222
export function multiselect(context: Context, command: Command): Context {
2323

2424
if (
2525
command.type === "SELECT ONE" &&
26-
listIncludesAndIsNotEmpty(context.list, command.id)
26+
listIncludesAndIsNotEmpty(context.index, command.id)
2727
) {
2828
return {
2929
...context,
@@ -32,23 +32,23 @@ export function multiselect(context: Context, command: Command): Context {
3232
};
3333
} else if (
3434
command.type === 'TOGGLE SELECTION' &&
35-
listIncludesAndIsNotEmpty(context.list, command.id) &&
35+
listIncludesAndIsNotEmpty(context.index, command.id) &&
3636
context.selected.includes(command.id) &&
3737
context.selected.length === 1
3838
) {
3939
return {
4040
...context,
4141
selected: [],
42-
adjacentPivot: head(context.list),
42+
adjacentPivot: head(context.index),
4343
};
4444
} else if (
4545
command.type === 'TOGGLE SELECTION' &&
46-
listIncludesAndIsNotEmpty(context.list, command.id) &&
46+
listIncludesAndIsNotEmpty(context.index, command.id) &&
4747
context.selected.includes(command.id)
4848
) {
4949
const selected = context.selected.filter(x => x !== command.id);
5050
const adjacentPivot = findNextPivot(
51-
context.list,
51+
context.index,
5252
selected,
5353
command.id
5454
);
@@ -60,7 +60,7 @@ export function multiselect(context: Context, command: Command): Context {
6060
};
6161
} else if (
6262
command.type === 'TOGGLE SELECTION' &&
63-
context.list.includes(command.id)
63+
context.index.includes(command.id)
6464
) {
6565
return {
6666
...context,
@@ -71,41 +71,41 @@ export function multiselect(context: Context, command: Command): Context {
7171
return {
7272
...context,
7373
selected: [],
74-
adjacentPivot: head(context.list)!,
74+
adjacentPivot: head(context.index)!,
7575
}
7676
} else if (
7777
command.type === "SELECT ADJACENT" &&
78-
listIncludesAndIsNotEmpty(context.list, command.id) &&
78+
listIncludesAndIsNotEmpty(context.index, command.id) &&
7979
context.selected.length === 0
8080
) {
81-
const n = context.list.indexOf(command.id) + 1;
81+
const n = context.index.indexOf(command.id) + 1;
8282
return {
8383
...context,
84-
selected: take(n, context.list),
85-
adjacentPivot: head(context.list),
84+
selected: take(n, context.index),
85+
adjacentPivot: head(context.index),
8686
}
8787
} else if (
8888
command.type === "SELECT ADJACENT" &&
89-
listIncludesAndIsNotEmpty(context.list, command.id) &&
89+
listIncludesAndIsNotEmpty(context.index, command.id) &&
9090
context.adjacentPivot !== undefined
9191
) {
9292

93-
const pivotIndex = context.list.indexOf(context.adjacentPivot);
94-
const selectionIndex = context.list.indexOf(command.id);
93+
const pivotIndex = context.index.indexOf(context.adjacentPivot);
94+
const selectionIndex = context.index.indexOf(command.id);
9595

9696
const adjacentToStart = findAdjacentToPivotInSortedArray(
97-
context.list,
97+
context.index,
9898
context.selected,
9999
context.adjacentPivot
100100
);
101101

102102
const adjacentToEnd = findAdjacentToPivotInSortedArray(
103-
context.list,
103+
context.index,
104104
context.selected,
105105
command.id,
106106
);
107107

108-
const nextSelection = context.list.slice(
108+
const nextSelection = context.index.slice(
109109
Math.min(pivotIndex, selectionIndex),
110110
Math.max(pivotIndex, selectionIndex) + 1
111111
);
@@ -122,36 +122,36 @@ export function multiselect(context: Context, command: Command): Context {
122122
}
123123
} else if(
124124
command.type === "SELECT NEXT" &&
125-
context.list.length &&
125+
context.index.length &&
126126
context.selected.length === 0
127127
) {
128128
return {
129129
...context,
130-
selected: [context.list[0]],
131-
adjacentPivot: context.list[0],
130+
selected: [context.index[0]],
131+
adjacentPivot: context.index[0],
132132
}
133133
} else if (
134134
command.type === "SELECT NEXT" &&
135-
context.list.length &&
135+
context.index.length &&
136136
context.selected.length
137137
) {
138-
const pivotIndex = context.list.indexOf(last(context.selected)!)
138+
const pivotIndex = context.index.indexOf(last(context.selected)!)
139139

140-
if (pivotIndex < context.list.length - 1) {
141-
const nextItem = context.list[pivotIndex + 1];
140+
if (pivotIndex < context.index.length - 1) {
141+
const nextKey = context.index[pivotIndex + 1];
142142

143143
return {
144144
...context,
145-
selected: [nextItem],
146-
adjacentPivot: nextItem
145+
selected: [nextKey],
146+
adjacentPivot: nextKey
147147
}
148148
} else if (
149149
!(
150150
context.selected.length === 1 &&
151-
context.selected[0] === last(context.list)
151+
context.selected[0] === last(context.index)
152152
)
153153
) {
154-
const pivot = context.list[pivotIndex];
154+
const pivot = context.index[pivotIndex];
155155
return {
156156
...context,
157157
selected: [pivot],
@@ -162,36 +162,36 @@ export function multiselect(context: Context, command: Command): Context {
162162
}
163163
} else if (
164164
command.type === "SELECT PREVIOUS" &&
165-
context.list.length &&
165+
context.index.length &&
166166
context.selected.length === 0
167167
) {
168-
const pivot = last(context.list)!;
168+
const pivot = last(context.index)!;
169169
return {
170170
...context,
171171
selected: [pivot],
172172
adjacentPivot: pivot,
173173
}
174174
} else if (
175175
command.type === "SELECT PREVIOUS" &&
176-
context.list.length &&
176+
context.index.length &&
177177
context.selected.length
178178
) {
179-
const pivotIndex = context.list.indexOf(last(context.selected)!)
179+
const pivotIndex = context.index.indexOf(last(context.selected)!)
180180

181181
if (pivotIndex > 0) {
182-
const prevItem = context.list[pivotIndex - 1];
182+
const prevKey = context.index[pivotIndex - 1];
183183
return {
184184
...context,
185-
selected: [prevItem],
186-
adjacentPivot: prevItem
185+
selected: [prevKey],
186+
adjacentPivot: prevKey
187187
}
188188
} else if (
189189
!(
190190
context.selected.length === 1 &&
191-
context.selected[0] === head(context.list)
191+
context.selected[0] === head(context.index)
192192
)
193193
) {
194-
const pivot = head(context.list)!;
194+
const pivot = head(context.index)!;
195195
return {
196196
...context,
197197
selected: [pivot],

0 commit comments

Comments
 (0)