Added "tabindex" property

This commit is contained in:
anoshenko 2022-12-20 18:38:39 +03:00
parent c5485c27c2
commit 3c3271663d
5 changed files with 65 additions and 5 deletions

View File

@ -690,4 +690,12 @@ const (
// "color-dodge" (6), "color-burn" (7), "hard-light" (8), "soft-light" (9), "difference" (10), // "color-dodge" (6), "color-burn" (7), "hard-light" (8), "soft-light" (9), "difference" (10),
// "exclusion" (11), "hue" (12), "saturation" (13), "color" (14), "luminosity" (15). // "exclusion" (11), "hue" (12), "saturation" (13), "color" (14), "luminosity" (15).
MixBlendMode = "mix-blend-mode" MixBlendMode = "mix-blend-mode"
// TabIndex is the constant for the "tabindex" property tag.
// The "tabindex" int property indicates that View can be focused, and where it participates in sequential keyboard navigation
// (usually with the Tab key, hence the name).
// * A negative value means that View is not reachable via sequential keyboard navigation, but could be focused by clicking with the mouse or touching.
// * tabindex="0" means that View should be focusable in sequential keyboard navigation, after any positive tabindex values and its order is defined in order of its addition.
// * A positive value means View should be focusable in sequential keyboard navigation, with its order defined by the value of the number.
TabIndex = "tabindex"
) )

View File

@ -74,6 +74,7 @@ var intProperties = []string{
ColumnSpan, ColumnSpan,
ColumnCount, ColumnCount,
Order, Order,
TabIndex,
} }
var floatProperties = map[string]struct{ min, max float64 }{ var floatProperties = map[string]struct{ min, max float64 }{

View File

@ -606,7 +606,8 @@ func (table *tableViewData) propertyChanged(tag string) {
switch GetTableSelectionMode(table) { switch GetTableSelectionMode(table) {
case CellSelection: case CellSelection:
session.updateProperty(htmlID, "tabindex", "0") tabIndex, _ := intProperty(table, TabIndex, session, 0)
session.updateProperty(htmlID, "tabindex", tabIndex)
session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)") session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)")
session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)") session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)")
session.updateProperty(htmlID, "data-selection", "cell") session.updateProperty(htmlID, "data-selection", "cell")
@ -621,7 +622,8 @@ func (table *tableViewData) propertyChanged(tag string) {
session.updateProperty(htmlID, "onkeydown", "tableViewCellKeyDownEvent(this, event)") session.updateProperty(htmlID, "onkeydown", "tableViewCellKeyDownEvent(this, event)")
case RowSelection: case RowSelection:
session.updateProperty(htmlID, "tabindex", "0") tabIndex, _ := intProperty(table, TabIndex, session, 0)
session.updateProperty(htmlID, "tabindex", tabIndex)
session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)") session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)")
session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)") session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)")
session.updateProperty(htmlID, "data-selection", "row") session.updateProperty(htmlID, "data-selection", "row")
@ -636,7 +638,11 @@ func (table *tableViewData) propertyChanged(tag string) {
session.updateProperty(htmlID, "onkeydown", "tableViewRowKeyDownEvent(this, event)") session.updateProperty(htmlID, "onkeydown", "tableViewRowKeyDownEvent(this, event)")
default: // NoneSelection default: // NoneSelection
for _, prop := range []string{"tabindex", "data-current", "onfocus", "onblur", "onkeydown", "data-selection"} { if tabIndex, ok := intProperty(table, TabIndex, session, -1); !ok || tabIndex < 0 {
session.removeProperty(htmlID, "tabindex")
}
for _, prop := range []string{"data-current", "onfocus", "onblur", "onkeydown", "data-selection"} {
session.removeProperty(htmlID, prop) session.removeProperty(htmlID, prop)
} }
} }

28
view.go
View File

@ -187,6 +187,14 @@ func (view *viewData) remove(tag string) {
case ID: case ID:
view.viewID = "" view.viewID = ""
case TabIndex, "tab-index":
delete(view.properties, tag)
if view.Focusable() {
view.session.updateProperty(view.htmlID(), "tabindex", "0")
} else {
view.session.updateProperty(view.htmlID(), "tabindex", "-1")
}
case UserData: case UserData:
delete(view.properties, tag) delete(view.properties, tag)
@ -312,6 +320,18 @@ func (view *viewData) set(tag string, value any) bool {
} }
view.viewID = text view.viewID = text
case TabIndex, "tab-index":
if !view.setIntProperty(tag, value) {
return false
}
if value, ok := intProperty(view, TabIndex, view.Session(), 0); ok {
view.session.updateProperty(view.htmlID(), "tabindex", strconv.Itoa(value))
} else if view.Focusable() {
view.session.updateProperty(view.htmlID(), "tabindex", "0")
} else {
view.session.updateProperty(view.htmlID(), "tabindex", "-1")
}
case UserData: case UserData:
view.properties[tag] = value view.properties[tag] = value
@ -758,9 +778,15 @@ func viewHTML(view View, buffer *strings.Builder) {
buffer.WriteRune(' ') buffer.WriteRune(' ')
} }
if view.Focusable() && !disabled { if !disabled {
if value, ok := intProperty(view, TabIndex, view.Session(), -1); ok {
buffer.WriteString(`tabindex="`)
buffer.WriteString(strconv.Itoa(value))
buffer.WriteString(`" `)
} else if view.Focusable() {
buffer.WriteString(`tabindex="0" `) buffer.WriteString(`tabindex="0" `)
} }
}
buffer.WriteString(`onscroll="scrollEvent(this, event)" `) buffer.WriteString(`onscroll="scrollEvent(this, event)" `)

View File

@ -153,6 +153,25 @@ func GetOverflow(view View, subviewID ...string) int {
return enumStyledProperty(view, subviewID, Overflow, defaultOverflow, false) return enumStyledProperty(view, subviewID, Overflow, defaultOverflow, false)
} }
// GetTabIndex returns the subview tab-index.
// If the second argument (subviewID) is not specified or it is "" then a tab-index of the first argument (view) is returned
func GetTabIndex(view View, subviewID ...string) int {
if len(subviewID) > 0 && subviewID[0] != "" {
view = ViewByID(view, subviewID[0])
}
defaultValue := -1
if view != nil {
if view.Focusable() {
defaultValue = 0
}
if value, ok := intProperty(view, TabIndex, view.Session(), defaultValue); ok {
return value
}
}
return defaultValue
}
// GetZIndex returns the subview z-order. // GetZIndex returns the subview z-order.
// If the second argument (subviewID) is not specified or it is "" then a z-order of the first argument (view) is returned // If the second argument (subviewID) is not specified or it is "" then a z-order of the first argument (view) is returned
func GetZIndex(view View, subviewID ...string) int { func GetZIndex(view View, subviewID ...string) int {