Skip to content

Commit c379fc5

Browse files
committed
add aria attributes to delete icon
1 parent a42186e commit c379fc5

File tree

3 files changed

+34
-29
lines changed

3 files changed

+34
-29
lines changed

templates/repo/home.tmpl

+5-5
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@
3636
{{if and .Permission.IsAdmin (not .Repository.IsArchived)}}
3737
<div class="ui form gt-hidden gt-df gt-mt-4" id="topic_edit">
3838
<div class="field gt-f1 gt-mr-3">
39-
<div class="ui fluid multiple search selection dropdown">
39+
<div class="ui fluid multiple search selection dropdown"
40+
data-text-count-prompt="{{.locale.Tr "repo.topic.count_prompt"}}"
41+
data-text-format-prompt="{{.locale.Tr "repo.topic.format_prompt"}}"
42+
data-text-remove="{{.locale.Tr "remove"}}"
43+
>
4044
<input type="hidden" name="topics" value="{{range $i, $v := .Topics}}{{.Name}}{{if lt (Add $i 1) (len $.Topics)}},{{end}}{{end}}">
4145
{{range .Topics}}
4246
{{/* lalels generated by Fomantic still use `<i class="delete icon">`, to avoid mixing different style together and to remind future developers, use it instead of svg*/}}
@@ -51,10 +55,6 @@
5155
</div>
5256
</div>
5357
{{end}}
54-
<div class="gt-hidden" id="validate_prompt">
55-
<span id="count_prompt">{{.locale.Tr "repo.topic.count_prompt"}}</span>
56-
<span id="format_prompt">{{.locale.Tr "repo.topic.format_prompt"}}</span>
57-
</div>
5858
{{if .Repository.IsArchived}}
5959
<div class="ui warning message">
6060
{{.locale.Tr "repo.archive.title"}}

web_src/js/features/aria.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ function generateAriaId() {
66
return `_aria_auto_id_${ariaIdCounter++}`;
77
}
88

9-
// make the item has role=option, and add an id if there wasn't one yet.
9+
// make the item has role=menuitem/option, and add an id if there wasn't one yet.
1010
function prepareMenuItem($item) {
1111
if (!$item.attr('id')) $item.attr('id', generateAriaId());
1212
$item.attr({'role': 'menuitem', 'tabindex': '-1'});
1313
$item.find('a').attr('tabindex', '-1'); // as above, the elements inside the dropdown menu item should not be focusable, the focus should always be on the dropdown primary element.
1414
}
1515

16-
// when the menu items are loaded from AJAX requests, the items are created dynamically
16+
// when the dropdown menu items are loaded from AJAX requests, the items are created dynamically
1717
const defaultCreateDynamicMenu = $.fn.dropdown.settings.templates.menu;
1818
$.fn.dropdown.settings.templates.menu = function(response, fields, preserveHTML, className) {
1919
const ret = defaultCreateDynamicMenu(response, fields, preserveHTML, className);
@@ -33,7 +33,7 @@ function attachOneDropdownAria($dropdown) {
3333
const $focusable = $textSearch.length ? $textSearch : $dropdown; // see comment below
3434
if (!$focusable.length) return;
3535

36-
// prepare menu list
36+
// prepare dropdown menu list
3737
const $menu = $dropdown.find('> .menu');
3838
if (!$menu.attr('id')) $menu.attr('id', generateAriaId());
3939

@@ -50,6 +50,7 @@ function attachOneDropdownAria($dropdown) {
5050
// - otherwise, the dropdown control (low-level code) handles the Enter event, hides the dropdown menu
5151

5252
// TODO: multiple selection is not supported yet.
53+
// TODO: use combobox for dropdown with search input in the future
5354

5455
$focusable.attr({
5556
'role': 'menu',

web_src/js/features/repo-home.js

+25-21
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,39 @@ const {appSubUrl, csrfToken} = window.config;
66

77
export function initRepoTopicBar() {
88
const mgrBtn = $('#manage_topic');
9-
const editDiv = $('#topic_edit');
10-
const viewDiv = $('#repo-topics');
9+
if (!mgrBtn.length) return;
10+
1111
const saveBtn = $('#save_topic');
12+
const topicListDiv = $('#repo-topics');
1213
const topicDropdown = $('#topic_edit .dropdown');
1314
const topicDropdownSearch = topicDropdown.find('input.search');
1415
const topicForm = $('#topic_edit');
15-
const topicPrompts = getPrompts();
16+
const topicPrompts = {
17+
countPrompt: topicDropdown.attr('data-text-count-prompt'),
18+
formatPrompt: topicDropdown.attr('data-text-format-prompt'),
19+
remove: topicDropdown.attr('data-text-remove'),
20+
};
21+
22+
function addLabelDeleteIconAria($el) {
23+
$el.attr({
24+
'aria-label': topicPrompts.remove,
25+
'role': 'button',
26+
});
27+
}
1628

1729
mgrBtn.on('click', () => {
18-
hideElem(viewDiv);
19-
showElem(editDiv);
30+
hideElem(topicListDiv);
31+
showElem(topicForm);
32+
addLabelDeleteIconAria(topicDropdown.find('i.delete.icon'));
2033
topicDropdownSearch.focus();
2134
});
2235

2336
$('#cancel_topic_edit').on('click', () => {
24-
hideElem(editDiv);
25-
showElem(viewDiv);
37+
hideElem(topicForm);
38+
showElem(topicListDiv);
2639
mgrBtn.focus();
2740
});
2841

29-
function getPrompts() {
30-
const hidePrompt = $('#validate_prompt');
31-
const prompts = {
32-
countPrompt: hidePrompt.children('#count_prompt').text(),
33-
formatPrompt: hidePrompt.children('#format_prompt').text()
34-
};
35-
hidePrompt.remove();
36-
return prompts;
37-
}
38-
3942
saveBtn.on('click', () => {
4043
const topics = $('input[name=topics]').val();
4144

@@ -44,7 +47,7 @@ export function initRepoTopicBar() {
4447
topics
4548
}, (_data, _textStatus, xhr) => {
4649
if (xhr.responseJSON.status === 'ok') {
47-
viewDiv.children('.topic').remove();
50+
topicListDiv.children('.topic').remove();
4851
if (topics.length) {
4952
const topicArray = topics.split(',');
5053
for (let i = 0; i < topicArray.length; i++) {
@@ -54,8 +57,8 @@ export function initRepoTopicBar() {
5457
link.insertBefore(mgrBtn); // insert all new topics before manage button
5558
}
5659
}
57-
hideElem(editDiv);
58-
showElem(viewDiv);
60+
hideElem(topicForm);
61+
showElem(topicListDiv);
5962
}
6063
}).fail((xhr) => {
6164
if (xhr.status === 422) {
@@ -147,7 +150,8 @@ export function initRepoTopicBar() {
147150
onLabelCreate(value) {
148151
value = value.toLowerCase().trim();
149152
this.attr('data-value', value).contents().first().replaceWith(value);
150-
return $(this);
153+
addLabelDeleteIconAria(this.find('i.delete.icon'));
154+
return this;
151155
},
152156
onAdd(addedValue, _addedText, $addedChoice) {
153157
addedValue = addedValue.toLowerCase().trim();

0 commit comments

Comments
 (0)