qsharp-lang 1.0.34-dev → 1.1.0-dev

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.
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT License.
3
3
 
4
- import { useRef, useState } from "preact/hooks";
4
+ import { useRef, useState, useEffect } from "preact/hooks";
5
5
 
6
6
  export type CellValue = string | number | { value: string; sortBy: number };
7
7
  export type Row = {
@@ -14,10 +14,9 @@ export function ResultsTable(props: {
14
14
  columnNames: string[];
15
15
  rows: Row[];
16
16
  initialColumns: number[];
17
- ensureSelected: boolean;
18
17
  onRowDeleted(rowId: string): void;
19
- selectedRow: string | null; // type selected to confirm with the useState pattern on the parent component
20
- setSelectedRow(rowId: string): void;
18
+ selectedRow: string | null;
19
+ onRowSelected(rowId: string): void;
21
20
  }) {
22
21
  const [showColumns, setShowColumns] = useState(props.initialColumns);
23
22
  const [sortColumn, setSortColumn] = useState<{
@@ -28,26 +27,9 @@ export function ResultsTable(props: {
28
27
  const [showColumnMenu, setShowColumnMenu] = useState(false);
29
28
  const [showRowMenu, setShowRowMenu] = useState("");
30
29
 
31
- // Find the first row that is new in the current sort order
32
- const newest = getSortedRows(props.rows).find(
33
- (row) => (row.cells[row.cells.length - 1] as string) === "New",
34
- );
35
-
36
- // Select the first of the newest rows, otherwise preserve the existing selection
37
- if (newest && props.ensureSelected) {
38
- const rowId = newest.cells[0].toString();
39
- setSelectedRow(rowId);
40
- } else if (
41
- !props.selectedRow &&
42
- props.ensureSelected &&
43
- props.rows.length > 0
44
- ) {
45
- const rowId = props.rows[0].cells[0].toString();
46
- setSelectedRow(rowId);
47
- }
48
-
49
30
  // Use to track the column being dragged
50
31
  const draggingCol = useRef("");
32
+ const columnMenu = useRef<HTMLDivElement>(null);
51
33
 
52
34
  /*
53
35
  Note: Drag and drop events can occur faster than preact reconciles state.
@@ -83,8 +65,8 @@ export function ResultsTable(props: {
83
65
  }
84
66
  }
85
67
 
86
- function setSelectedRow(rowId: string) {
87
- props.setSelectedRow(rowId);
68
+ function onRowSelected(rowId: string) {
69
+ props.onRowSelected(rowId);
88
70
  }
89
71
 
90
72
  function onDragOver(ev: DragEvent) {
@@ -200,11 +182,9 @@ export function ResultsTable(props: {
200
182
  }
201
183
  }
202
184
 
203
- function rowClicked(rowId: string) {
204
- if (props.selectedRow === rowId && props.ensureSelected) return;
205
-
185
+ function onRowClicked(rowId: string) {
206
186
  const newSelectedRow = props.selectedRow === rowId ? "" : rowId;
207
- setSelectedRow(newSelectedRow);
187
+ onRowSelected(newSelectedRow);
208
188
  }
209
189
 
210
190
  function onClickRowMenu(ev: MouseEvent, rowid: string) {
@@ -254,17 +234,59 @@ export function ResultsTable(props: {
254
234
  // Clear out any menus or selections for the row if needed
255
235
  setShowRowMenu("");
256
236
  if (props.selectedRow === rowId) {
257
- setSelectedRow("");
237
+ onRowSelected("");
258
238
  }
259
239
  props.onRowDeleted(rowId);
260
240
  }
261
241
 
242
+ function onKeyDown(ev: KeyboardEvent) {
243
+ if (!props.selectedRow) return;
244
+ const sortedRowNames = getSortedRows(props.rows).map((row) =>
245
+ row.cells[0].toString(),
246
+ );
247
+ const currIndex = sortedRowNames.indexOf(props.selectedRow);
248
+
249
+ switch (ev.code) {
250
+ case "ArrowDown":
251
+ if (currIndex < sortedRowNames.length - 1) {
252
+ ev.preventDefault();
253
+ props.onRowSelected(sortedRowNames[currIndex + 1]);
254
+ }
255
+ break;
256
+ case "ArrowUp":
257
+ if (currIndex > 0) {
258
+ ev.preventDefault();
259
+ props.onRowSelected(sortedRowNames[currIndex - 1]);
260
+ }
261
+ break;
262
+ default:
263
+ // Not of interest
264
+ }
265
+ }
266
+
267
+ useEffect(() => {
268
+ // Post rendering, if the column menu is displayed, then ensure it
269
+ // has focus so that clicking anywhere outside of it caused the blur
270
+ // event that closes it.
271
+ if (showColumnMenu && columnMenu.current) {
272
+ columnMenu.current.focus();
273
+ }
274
+ });
275
+
262
276
  return (
263
- <table class="qs-resultsTable-sortedTable">
277
+ <table
278
+ class="qs-resultsTable-sortedTable"
279
+ tabIndex={0}
280
+ onKeyDown={onKeyDown}
281
+ >
264
282
  <thead>
265
283
  <tr>
266
284
  <th>
267
- <div style="position: relative">
285
+ <div
286
+ style="position: relative"
287
+ tabIndex={0}
288
+ onBlur={() => setShowColumnMenu(false)}
289
+ >
268
290
  <svg
269
291
  width="16"
270
292
  height="16"
@@ -289,6 +311,7 @@ export function ResultsTable(props: {
289
311
  />
290
312
  </svg>
291
313
  <div
314
+ ref={columnMenu}
292
315
  class={
293
316
  showColumnMenu
294
317
  ? "qs-resultsTable-columnMenu qs-resultsTable-showColumnMenu"
@@ -354,7 +377,7 @@ export function ResultsTable(props: {
354
377
  const rowId = row.cells[0].toString();
355
378
  return (
356
379
  <tr
357
- onClick={() => rowClicked(rowId)}
380
+ onClick={() => onRowClicked(rowId)}
358
381
  data-rowid={rowId}
359
382
  class={
360
383
  rowId === props.selectedRow