feat(GridView): allows navigation by arrow keys
All checks were successful
AntOS front-end / Build-AntOS-Frontend (push) Successful in 35s

This commit is contained in:
DanyLE 2024-07-28 19:05:34 +02:00
parent 4bbc6c770a
commit 59fb302e18
9 changed files with 202 additions and 12 deletions

View File

@ -8,7 +8,7 @@ TSC=./node_modules/typescript/bin/tsc
UGLIFYJS=./node_modules/terser/bin/terser
UGLIFYCSS=./node_modules/uglifycss/uglifycss
VERSION?=2.0.2-b
VERSION?=2.0.3-b
BUILDID?=master
GSED=sed

53
d.ts/antos.d.ts vendored
View File

@ -4780,14 +4780,14 @@ declare namespace OS {
* @returns {void}
* @memberof ListViewTag
*/
nav_next(): void;
nav_prev(): void;
/**
* Navigate the list down
*
* @returns {void}
* @memberof ListViewTag
*/
nav_prev(): void;
nav_next(): void;
/**
* Commit the navigated item
*
@ -6300,6 +6300,13 @@ declare namespace OS {
* @memberof GridViewTag
*/
private _dnd;
/**
* Grid navigation index
*
* @private
* @type {number}
*/
private _nav_index;
/**
* placeholder of list drag and drop event handle
*
@ -6480,6 +6487,12 @@ declare namespace OS {
* @memberof GridViewTag
*/
delete(row: GridRowTag): void;
/**
* Scroll the grid view to item
*
* @memberof GridViewTag
*/
scroll_to_item(item: GridRowTag): void;
/**
* Scroll the grid view to bottom
*
@ -6559,6 +6572,42 @@ declare namespace OS {
* @memberof GridViewTag
*/
private calibrate_header;
/**
* Reset the navigation indicator
*
* @private
*/
private nav_reset;
/**
* Navigate the list up
*
* @public
* @returns {void}
* @memberof ListViewTag
*/
nav_prev(): void;
/**
* Navigate the list down
*
* @returns {void}
* @memberof ListViewTag
*/
nav_next(): void;
/**
* Commit the navigated item
*
* @returns {void}
* @memberof ListViewTag
*/
nav_commit(): void;
/**
* Handle special key event such as key up and down
*
* @private
* @param {JQuery.KeyboardEventBase} event
* @returns {void}
*/
private handle_special_key;
/**
* Mount the grid view tag
*

View File

@ -685,7 +685,7 @@ namespace OS {
InfoDialog.scheme = `\
<afx-app-window width='300' height='350' apptitle = "Info" >
<afx-vbox padding = "10">
<afx-grid-view data-id = "grid" ></afx-grid-view>
<afx-grid-view data-id = "grid" focusable="true"></afx-grid-view>
<div data-height="35" style="text-align: right;">
<afx-button data-id = "btnCancel" text = "__(Cancel)"></afx-button>
</div>

View File

@ -497,6 +497,14 @@ namespace OS {
*/
private _dnd: { from: GridRowTag[]; to: GridRowTag };
/**
* Grid navigation index
*
* @private
* @type {number}
*/
private _nav_index: number;
/**
* placeholder of list drag and drop event handle
*
@ -514,6 +522,7 @@ namespace OS {
*/
constructor() {
super();
this._nav_index = -1;
}
/**
@ -883,6 +892,35 @@ namespace OS {
}
$(row).remove();
}
/**
* Scroll the grid view to item
*
* @memberof GridViewTag
*/
scroll_to_item(item: GridRowTag)
{
const cell = $(item).children()[0];
const offset = $(this.refs.container).offset();
const cell_offset = $(cell).offset();
const top = $(this.refs.container).scrollTop();
const cell_height = $(cell).outerHeight();
const container_height = $(this.refs.container).outerHeight();
if (cell_offset.top + cell_height > container_height + offset.top)
{
$(this.refs.container).scrollTop(
top +
(cell_offset.top + cell_height - offset.top - container_height)
);
} else if (cell_offset.top < offset.top) {
$(this.refs.container).scrollTop(
top -
(offset.top - cell_offset.top)
);
}
}
/**
* Scroll the grid view to bottom
*
@ -1042,6 +1080,7 @@ namespace OS {
}
evt.data.item = row;
this._selectedRow = row;
this._nav_index = $(row).index();
this._onrowselect(evt);
return this.observable.trigger("rowselect", evt);
}
@ -1152,6 +1191,101 @@ namespace OS {
}
}
/**
* Reset the navigation indicator
*
* @private
*/
private nav_reset() {
const el = $(this.refs.grid).children().eq(this._nav_index);
if(el)
{
$(el).removeClass("gridview-nav-focus");
}
}
/**
* Navigate the list up
*
* @public
* @returns {void}
* @memberof ListViewTag
*/
public nav_prev() {
console.log("nav_prev");
if(this._nav_index <= 0) {
return;
}
this.nav_reset();
this._nav_index--;
const el = $(this.refs.grid).children().eq(this._nav_index);
if(el) {
$(el).addClass("gridview-nav-focus");
this.scroll_to_item(el[0] as GridRowTag);
}
}
/**
* Navigate the list down
*
* @returns {void}
* @memberof ListViewTag
*/
public nav_next() {
console.log("nav_next");
if(this._nav_index >= this.rows.length - 1) {
return;
}
this.nav_reset();
this._nav_index++;
const el = $(this.refs.grid).children().eq(this._nav_index);
if(el) {
$(el).addClass("gridview-nav-focus");
this.scroll_to_item(el[0] as GridRowTag);
}
}
/**
* Commit the navigated item
*
* @returns {void}
* @memberof ListViewTag
*/
public nav_commit() {
if(this._nav_index > this.rows.length - 1 || this._nav_index < 0) {
return;
}
const el = $(this.refs.grid).children().eq(this._nav_index);
if(el) {
(el[0] as GridRowTag).selected = true;
}
}
/**
* Handle special key event such as key up and down
*
* @private
* @param {JQuery.KeyboardEventBase} event
* @returns {void}
*/
private handle_special_key(event: JQuery.KeyboardEventBase) {
switch (event.which) {
case 37:
case 38:
this.nav_prev();
return event.preventDefault();
case 39:
case 40:
this.nav_next();
return event.preventDefault();
case 13:
event.preventDefault();
return this.nav_commit();
default:
break;
}
}
/**
* Mount the grid view tag
*
@ -1160,6 +1294,9 @@ namespace OS {
* @memberof GridViewTag
*/
protected mount(): void {
$(this).on("keyup", (e) => {
this.handle_special_key(e);
});
$(this).css("overflow", "hidden");
$(this.refs.grid).css("display", "grid");
$(this.refs.header).css("display", "grid");

View File

@ -1122,7 +1122,7 @@ namespace OS {
* @returns {void}
* @memberof ListViewTag
*/
public nav_next() {
public nav_prev() {
if(this._nav_index <= 0) {
return;
}
@ -1141,7 +1141,7 @@ namespace OS {
* @returns {void}
* @memberof ListViewTag
*/
public nav_prev() {
public nav_next() {
if(this._nav_index >= this.data.length - 1) {
return;
}
@ -1179,11 +1179,11 @@ namespace OS {
switch (event.which) {
case 37:
case 38:
this.nav_next();
this.nav_prev();
return event.preventDefault();
case 39:
case 40:
this.nav_prev();
this.nav_next();
return event.preventDefault();
case 13:
event.preventDefault();

View File

@ -156,12 +156,12 @@ namespace OS {
return this.toggle(false);
case 37:
applist.nav_next();
applist.nav_prev();
return e.preventDefault();
case 38:
return e.preventDefault();
case 39:
applist.nav_prev();
applist.nav_next();
return e.preventDefault();
case 40:
return e.preventDefault();

View File

@ -6,7 +6,7 @@
"author": "Xuan Sang LE",
"email": "xsang.le@gmail.com"
},
"version":"0.2.1-b",
"version":"0.2.2-b",
"category":"System",
"iconclass":"fa fa-wrench",
"mimes":["none"]

View File

@ -75,7 +75,7 @@
<afx-hbox data-id="app-about" tabname = "__(Versions)" iconclass = "bi bi-info-square" padding="10">
<afx-vbox>
<afx-label text = "__(System versions)" iconclass = "bi bi-gear-wide-connected" class = "header" data-height="30"></afx-label>
<afx-grid-view data-id="grid-version"></afx-grid-view>
<afx-grid-view data-id="grid-version" focusable="true"></afx-grid-view>
</afx-vbox>
</afx-hbox>

View File

@ -17,6 +17,10 @@ afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell
background-color: var(--item-bg-active);
color:var(--text-tertiary);
}
afx-grid-view afx-grid-row.gridview-nav-focus afx-grid-cell
{
background-color: var(--item-bg-hover);
}
afx-grid-view afx-grid-row.afx-grid-row-selected afx-grid-cell.afx-grid-cell-selected
{
font-weight: normal;