@invopop/popui 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,6 +13,9 @@ const callback = (entry) => {
13
13
  };
14
14
  const intersectOptions = { callback };
15
15
  let metaKeyPressed = false;
16
+ let shiftKeyPressed = false;
17
+ let lastSelected = {};
18
+ let selectWithArrowPosition = -1;
16
19
  export let sortBy = "";
17
20
  export let sortDirection = "";
18
21
  export let fields = [];
@@ -25,6 +28,7 @@ export let freeWrap = false;
25
28
  export let selectable = false;
26
29
  export let selectedRows = [];
27
30
  export let selectedTrackedBy = "id";
31
+ export let hideSelectAll = false;
28
32
  $:
29
33
  groupedData = groupData(data);
30
34
  $:
@@ -33,6 +37,12 @@ $:
33
37
  indeterminate = selectedRows.length > 0 && selectedRows.length < data.length;
34
38
  $:
35
39
  allChecked = selectedRows.length === data.length;
40
+ $:
41
+ flattedData = groupedData.flatMap((d) => d.rows);
42
+ $:
43
+ lastSelectedIndex = flattedData.findIndex(
44
+ (d) => d[selectedTrackedBy] === lastSelected[selectedTrackedBy]
45
+ );
36
46
  function groupData(rows) {
37
47
  if (rows.length === 0)
38
48
  return [];
@@ -50,18 +60,94 @@ function groupData(rows) {
50
60
  }
51
61
  function toggleAllSelected(selected) {
52
62
  selectedRows = [];
63
+ lastSelected = {};
53
64
  if (!selected)
54
65
  return;
55
66
  selectedRows = data;
56
67
  }
68
+ function selectRow(row) {
69
+ selectedRows = [.../* @__PURE__ */ new Set([...selectedRows, row])];
70
+ }
71
+ function unselectRow(row) {
72
+ selectedRows = selectedRows.filter((r) => r[selectedTrackedBy] !== row[selectedTrackedBy]);
73
+ if (!selectedRows.length) {
74
+ lastSelected = {};
75
+ }
76
+ }
77
+ function selectRange(to) {
78
+ if (lastSelectedIndex < 0)
79
+ return;
80
+ let fromIndex = lastSelectedIndex;
81
+ let toIndex = flattedData.findIndex((d) => d[selectedTrackedBy] === to[selectedTrackedBy]);
82
+ if (fromIndex > toIndex) {
83
+ ;
84
+ [fromIndex, toIndex] = [toIndex, fromIndex];
85
+ }
86
+ const itemsToSelect = flattedData.slice(fromIndex, toIndex + 1);
87
+ selectedRows = [.../* @__PURE__ */ new Set([...selectedRows, ...itemsToSelect])];
88
+ }
57
89
  </script>
58
90
 
59
91
  <svelte:window
60
92
  on:keydown={(event) => {
93
+ if (event.key === 'Escape' || event.key === 'Esc') {
94
+ selectedRows = []
95
+ lastSelected = {}
96
+ }
97
+
61
98
  metaKeyPressed = event.metaKey
99
+ shiftKeyPressed = event.shiftKey
100
+
101
+ if (event.key === 'Shift') {
102
+ selectWithArrowPosition = lastSelectedIndex
103
+ return
104
+ }
105
+
106
+ if (event.key === 'ArrowUp') {
107
+ if (!shiftKeyPressed) return
108
+ const toIndex = lastSelectedIndex - 1
109
+ const to = flattedData[toIndex]
110
+
111
+ if (!to) return
112
+
113
+ if (toIndex < selectWithArrowPosition) {
114
+ selectRow(to)
115
+ } else {
116
+ unselectRow(lastSelected)
117
+ }
118
+
119
+ lastSelected = to
120
+ }
121
+
122
+ if (event.key === 'ArrowDown') {
123
+ if (lastSelectedIndex < 0) {
124
+ selectRow(flattedData[0])
125
+ lastSelected = flattedData[0]
126
+ }
127
+
128
+ if (!shiftKeyPressed) return
129
+
130
+ const toIndex = lastSelectedIndex + 1
131
+ const to = flattedData[toIndex]
132
+
133
+ if (!to) return
134
+
135
+ if (toIndex > selectWithArrowPosition) {
136
+ selectRow(to)
137
+ } else {
138
+ unselectRow(lastSelected)
139
+ }
140
+
141
+ lastSelected = to
142
+ }
62
143
  }}
63
- on:keyup={() => {
144
+ on:keyup={(event) => {
64
145
  metaKeyPressed = false
146
+ shiftKeyPressed = false
147
+
148
+ if (!event.shiftKey) {
149
+ selectWithArrowPosition = -1
150
+ }
65
151
  }}
66
152
  />
67
153
 
@@ -72,13 +158,15 @@ function toggleAllSelected(selected) {
72
158
  {#if selectable}
73
159
  <!-- if table is selectable we need to add an extra header with a checkbox -->
74
160
  <th scope="col" class="bg-white sticky top-0 z-10 rounded-tr-md pl-1.5">
75
- <InputCheckbox
76
- checked={allChecked}
77
- {indeterminate}
78
- on:change={(event) => {
79
- toggleAllSelected(event.detail)
80
- }}
81
- />
161
+ {#if !hideSelectAll}
162
+ <InputCheckbox
163
+ checked={allChecked}
164
+ {indeterminate}
165
+ on:change={(event) => {
166
+ toggleAllSelected(event.detail)
167
+ }}
168
+ />
169
+ {/if}
82
170
  </th>
83
171
  {/if}
84
172
  {#each fields as field, i (i)}
@@ -137,11 +225,14 @@ function toggleAllSelected(selected) {
137
225
  }}
138
226
  on:checked={(event) => {
139
227
  if (event.detail) {
140
- selectedRows = [...selectedRows, row]
228
+ if (shiftKeyPressed) {
229
+ selectRange(row)
230
+ } else {
231
+ selectRow(row)
232
+ }
233
+ lastSelected = row
141
234
  } else {
142
- selectedRows = selectedRows.filter(
143
- (r) => r[selectedTrackedBy] !== row[selectedTrackedBy]
144
- )
235
+ unselectRow(row)
145
236
  }
146
237
  }}
147
238
  on:action
@@ -14,6 +14,7 @@ declare const __propDef: {
14
14
  selectable?: boolean | undefined;
15
15
  selectedRows?: TableDataRow[] | undefined;
16
16
  selectedTrackedBy?: string | undefined;
17
+ hideSelectAll?: boolean | undefined;
17
18
  };
18
19
  events: {
19
20
  orderBy: CustomEvent<any>;
@@ -25,6 +25,7 @@ $:
25
25
 
26
26
  <tr
27
27
  class:cursor-pointer={!disableRowClick}
28
+ class:bg-workspace-accent-50={checked}
28
29
  class="hover:bg-neutral-50"
29
30
  on:click
30
31
  on:contextmenu|preventDefault={() => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@invopop/popui",
3
3
  "license": "MIT",
4
- "version": "0.0.6",
4
+ "version": "0.0.7",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
7
7
  "build": "vite build && npm run package",