primer_view_components 0.0.122 → 0.0.123
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/components/primer/alpha/action_list/item.rb +7 -0
- data/app/components/primer/alpha/nav_list/item.rb +4 -0
- data/app/components/primer/alpha/nav_list/section.rb +1 -1
- data/app/components/primer/alpha/nav_list.d.ts +6 -3
- data/app/components/primer/alpha/nav_list.js +95 -6
- data/app/components/primer/alpha/nav_list.rb +5 -0
- data/app/components/primer/alpha/nav_list.ts +105 -3
- data/app/components/primer/component.rb +1 -1
- data/lib/primer/view_components/version.rb +1 -1
- metadata +1 -1
@@ -187,6 +187,9 @@ module Primer
|
|
187
187
|
@system_arguments[:aria] ||= {}
|
188
188
|
@system_arguments[:aria][:disabled] = "true" if @disabled
|
189
189
|
|
190
|
+
@system_arguments[:data] ||= {}
|
191
|
+
@system_arguments[:data][:targets] = "#{list_class.custom_element_name}.items"
|
192
|
+
|
190
193
|
@label_arguments = {
|
191
194
|
classes: class_names(
|
192
195
|
label_classes,
|
@@ -236,6 +239,10 @@ module Primer
|
|
236
239
|
"ActionListContent--blockDescription" => description && @description_scheme == :block
|
237
240
|
)
|
238
241
|
end
|
242
|
+
|
243
|
+
def list_class
|
244
|
+
Primer::Alpha::ActionList
|
245
|
+
end
|
239
246
|
end
|
240
247
|
end
|
241
248
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
declare class NavListElement extends HTMLElement {
|
1
|
+
export declare class NavListElement extends HTMLElement {
|
2
|
+
#private;
|
2
3
|
list: HTMLElement;
|
4
|
+
items: HTMLElement[];
|
3
5
|
showMoreItem: HTMLElement;
|
4
6
|
focusMarkers: HTMLElement[];
|
5
7
|
connectedCallback(): void;
|
@@ -9,17 +11,18 @@ declare class NavListElement extends HTMLElement {
|
|
9
11
|
get currentPage(): number;
|
10
12
|
get totalPages(): number;
|
11
13
|
get paginationSrc(): string;
|
14
|
+
selectItemById(itemId: string | null): boolean;
|
15
|
+
selectItemByHref(href: string | null): boolean;
|
16
|
+
selectItemByCurrentLocation(): boolean;
|
12
17
|
expandItem(item: HTMLElement): void;
|
13
18
|
collapseItem(item: HTMLElement): void;
|
14
19
|
itemIsExpanded(item: HTMLElement | null): boolean;
|
15
20
|
handleItemWithSubItemClick(e: Event): void;
|
16
21
|
private showMore;
|
17
22
|
private setShowMoreItemState;
|
18
|
-
private parseHTML;
|
19
23
|
}
|
20
24
|
declare global {
|
21
25
|
interface Window {
|
22
26
|
NavListElement: typeof NavListElement;
|
23
27
|
}
|
24
28
|
}
|
25
|
-
export {};
|
@@ -4,9 +4,19 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
6
6
|
};
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
11
|
+
};
|
12
|
+
var _NavListElement_instances, _NavListElement_parseHTML, _NavListElement_findSelectedNavItemById, _NavListElement_findSelectedNavItemByHref, _NavListElement_findSelectedNavItemByCurrentLocation, _NavListElement_select, _NavListElement_deselect, _NavListElement_findParentMenu;
|
7
13
|
/* eslint-disable custom-elements/expose-class-on-global */
|
8
14
|
import { controller, target, targets } from '@github/catalyst';
|
9
15
|
let NavListElement = class NavListElement extends HTMLElement {
|
16
|
+
constructor() {
|
17
|
+
super(...arguments);
|
18
|
+
_NavListElement_instances.add(this);
|
19
|
+
}
|
10
20
|
connectedCallback() {
|
11
21
|
this.setShowMoreItemState();
|
12
22
|
}
|
@@ -34,6 +44,34 @@ let NavListElement = class NavListElement extends HTMLElement {
|
|
34
44
|
get paginationSrc() {
|
35
45
|
return this.showMoreItem.getAttribute('src') || '';
|
36
46
|
}
|
47
|
+
selectItemById(itemId) {
|
48
|
+
if (!itemId)
|
49
|
+
return false;
|
50
|
+
const selectedItem = __classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_findSelectedNavItemById).call(this, itemId);
|
51
|
+
if (selectedItem) {
|
52
|
+
__classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_select).call(this, selectedItem);
|
53
|
+
return true;
|
54
|
+
}
|
55
|
+
return false;
|
56
|
+
}
|
57
|
+
selectItemByHref(href) {
|
58
|
+
if (!href)
|
59
|
+
return false;
|
60
|
+
const selectedItem = __classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_findSelectedNavItemByHref).call(this, href);
|
61
|
+
if (selectedItem) {
|
62
|
+
__classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_select).call(this, selectedItem);
|
63
|
+
return true;
|
64
|
+
}
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
selectItemByCurrentLocation() {
|
68
|
+
const selectedItem = __classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_findSelectedNavItemByCurrentLocation).call(this);
|
69
|
+
if (selectedItem) {
|
70
|
+
__classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_select).call(this, selectedItem);
|
71
|
+
return true;
|
72
|
+
}
|
73
|
+
return false;
|
74
|
+
}
|
37
75
|
// expand collapsible item onClick
|
38
76
|
expandItem(item) {
|
39
77
|
var _a;
|
@@ -92,7 +130,7 @@ let NavListElement = class NavListElement extends HTMLElement {
|
|
92
130
|
this.currentPage--;
|
93
131
|
return;
|
94
132
|
}
|
95
|
-
const fragment = this.
|
133
|
+
const fragment = __classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_parseHTML).call(this, document, html);
|
96
134
|
(_a = fragment === null || fragment === void 0 ? void 0 : fragment.querySelector('li > a')) === null || _a === void 0 ? void 0 : _a.setAttribute('data-targets', 'nav-list.focusMarkers');
|
97
135
|
this.list.insertBefore(fragment, this.showMoreItem);
|
98
136
|
(_b = this.focusMarkers.pop()) === null || _b === void 0 ? void 0 : _b.focus();
|
@@ -109,16 +147,66 @@ let NavListElement = class NavListElement extends HTMLElement {
|
|
109
147
|
this.showMoreItem.hidden = true;
|
110
148
|
}
|
111
149
|
}
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
150
|
+
};
|
151
|
+
_NavListElement_instances = new WeakSet(), _NavListElement_parseHTML = function _NavListElement_parseHTML(document, html) {
|
152
|
+
const template = document.createElement('template');
|
153
|
+
// eslint-disable-next-line github/no-inner-html
|
154
|
+
template.innerHTML = html;
|
155
|
+
return document.importNode(template.content, true);
|
156
|
+
}, _NavListElement_findSelectedNavItemById = function _NavListElement_findSelectedNavItemById(itemId) {
|
157
|
+
var _a;
|
158
|
+
// First we compare the selected link to data-item-id for each nav item
|
159
|
+
for (const navItem of this.items) {
|
160
|
+
const keys = ((_a = navItem.getAttribute('data-item-id')) === null || _a === void 0 ? void 0 : _a.split(' ')) || [];
|
161
|
+
if (keys.includes(itemId)) {
|
162
|
+
return navItem;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
return null;
|
166
|
+
}, _NavListElement_findSelectedNavItemByHref = function _NavListElement_findSelectedNavItemByHref(href) {
|
167
|
+
// If we didn't find a match, we compare the selected link to the href of each nav item
|
168
|
+
const selectedNavItem = this.querySelector(`.ActionListContent[href="${href}"]`);
|
169
|
+
if (selectedNavItem) {
|
170
|
+
return selectedNavItem.closest('.ActionListItem');
|
171
|
+
}
|
172
|
+
return null;
|
173
|
+
}, _NavListElement_findSelectedNavItemByCurrentLocation = function _NavListElement_findSelectedNavItemByCurrentLocation() {
|
174
|
+
return __classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_findSelectedNavItemByHref).call(this, window.location.pathname);
|
175
|
+
}, _NavListElement_select = function _NavListElement_select(navItem) {
|
176
|
+
const currentlySelectedItem = this.querySelector('.ActionListItem--navActive');
|
177
|
+
if (currentlySelectedItem)
|
178
|
+
__classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_deselect).call(this, currentlySelectedItem);
|
179
|
+
navItem.classList.add('ActionListItem--navActive');
|
180
|
+
const parentMenu = __classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_findParentMenu).call(this, navItem);
|
181
|
+
if (parentMenu) {
|
182
|
+
this.expandItem(parentMenu);
|
183
|
+
parentMenu.classList.add('ActionListContent--hasActiveSubItem');
|
184
|
+
}
|
185
|
+
}, _NavListElement_deselect = function _NavListElement_deselect(navItem) {
|
186
|
+
navItem.classList.remove('ActionListItem--navActive');
|
187
|
+
const parentMenu = __classPrivateFieldGet(this, _NavListElement_instances, "m", _NavListElement_findParentMenu).call(this, navItem);
|
188
|
+
if (parentMenu) {
|
189
|
+
this.collapseItem(parentMenu);
|
190
|
+
parentMenu.classList.remove('ActionListContent--hasActiveSubItem');
|
191
|
+
}
|
192
|
+
}, _NavListElement_findParentMenu = function _NavListElement_findParentMenu(navItem) {
|
193
|
+
var _a;
|
194
|
+
if (!navItem.classList.contains('ActionListItem--subItem'))
|
195
|
+
return null;
|
196
|
+
const parent = (_a = navItem.closest('li.ActionListItem--hasSubItem')) === null || _a === void 0 ? void 0 : _a.querySelector('button.ActionListContent');
|
197
|
+
if (parent) {
|
198
|
+
return parent;
|
199
|
+
}
|
200
|
+
else {
|
201
|
+
return null;
|
117
202
|
}
|
118
203
|
};
|
119
204
|
__decorate([
|
120
205
|
target
|
121
206
|
], NavListElement.prototype, "list", void 0);
|
207
|
+
__decorate([
|
208
|
+
targets
|
209
|
+
], NavListElement.prototype, "items", void 0);
|
122
210
|
__decorate([
|
123
211
|
target
|
124
212
|
], NavListElement.prototype, "showMoreItem", void 0);
|
@@ -128,3 +216,4 @@ __decorate([
|
|
128
216
|
NavListElement = __decorate([
|
129
217
|
controller
|
130
218
|
], NavListElement);
|
219
|
+
export { NavListElement };
|
@@ -17,6 +17,11 @@ module Primer
|
|
17
17
|
class NavList < Primer::Component
|
18
18
|
status :alpha
|
19
19
|
|
20
|
+
# @private
|
21
|
+
def self.custom_element_name
|
22
|
+
"nav-list"
|
23
|
+
end
|
24
|
+
|
20
25
|
# Sections. Each section is a list of links and an optional heading.
|
21
26
|
#
|
22
27
|
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Section) %>.
|
@@ -2,8 +2,9 @@
|
|
2
2
|
import {controller, target, targets} from '@github/catalyst'
|
3
3
|
|
4
4
|
@controller
|
5
|
-
class NavListElement extends HTMLElement {
|
5
|
+
export class NavListElement extends HTMLElement {
|
6
6
|
@target list: HTMLElement
|
7
|
+
@targets items: HTMLElement[]
|
7
8
|
@target showMoreItem: HTMLElement
|
8
9
|
@targets focusMarkers: HTMLElement[]
|
9
10
|
|
@@ -40,6 +41,43 @@ class NavListElement extends HTMLElement {
|
|
40
41
|
return this.showMoreItem.getAttribute('src') || ''
|
41
42
|
}
|
42
43
|
|
44
|
+
selectItemById(itemId: string | null): boolean {
|
45
|
+
if (!itemId) return false
|
46
|
+
|
47
|
+
const selectedItem = this.#findSelectedNavItemById(itemId)
|
48
|
+
|
49
|
+
if (selectedItem) {
|
50
|
+
this.#select(selectedItem)
|
51
|
+
return true
|
52
|
+
}
|
53
|
+
|
54
|
+
return false
|
55
|
+
}
|
56
|
+
|
57
|
+
selectItemByHref(href: string | null): boolean {
|
58
|
+
if (!href) return false
|
59
|
+
|
60
|
+
const selectedItem = this.#findSelectedNavItemByHref(href)
|
61
|
+
|
62
|
+
if (selectedItem) {
|
63
|
+
this.#select(selectedItem)
|
64
|
+
return true
|
65
|
+
}
|
66
|
+
|
67
|
+
return false
|
68
|
+
}
|
69
|
+
|
70
|
+
selectItemByCurrentLocation(): boolean {
|
71
|
+
const selectedItem = this.#findSelectedNavItemByCurrentLocation()
|
72
|
+
|
73
|
+
if (selectedItem) {
|
74
|
+
this.#select(selectedItem)
|
75
|
+
return true
|
76
|
+
}
|
77
|
+
|
78
|
+
return false
|
79
|
+
}
|
80
|
+
|
43
81
|
// expand collapsible item onClick
|
44
82
|
expandItem(item: HTMLElement) {
|
45
83
|
item.nextElementSibling?.removeAttribute('data-hidden')
|
@@ -95,7 +133,7 @@ class NavListElement extends HTMLElement {
|
|
95
133
|
this.currentPage--
|
96
134
|
return
|
97
135
|
}
|
98
|
-
const fragment = this
|
136
|
+
const fragment = this.#parseHTML(document, html)
|
99
137
|
fragment?.querySelector('li > a')?.setAttribute('data-targets', 'nav-list.focusMarkers')
|
100
138
|
this.list.insertBefore(fragment, this.showMoreItem)
|
101
139
|
this.focusMarkers.pop()?.focus()
|
@@ -114,12 +152,76 @@ class NavListElement extends HTMLElement {
|
|
114
152
|
}
|
115
153
|
}
|
116
154
|
|
117
|
-
|
155
|
+
#parseHTML(document: Document, html: string): DocumentFragment {
|
118
156
|
const template = document.createElement('template')
|
119
157
|
// eslint-disable-next-line github/no-inner-html
|
120
158
|
template.innerHTML = html
|
121
159
|
return document.importNode(template.content, true)
|
122
160
|
}
|
161
|
+
|
162
|
+
#findSelectedNavItemById(itemId: string): HTMLElement | null {
|
163
|
+
// First we compare the selected link to data-item-id for each nav item
|
164
|
+
for (const navItem of this.items) {
|
165
|
+
const keys = navItem.getAttribute('data-item-id')?.split(' ') || []
|
166
|
+
|
167
|
+
if (keys.includes(itemId)) {
|
168
|
+
return navItem
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
return null
|
173
|
+
}
|
174
|
+
|
175
|
+
#findSelectedNavItemByHref(href: string): HTMLElement | null {
|
176
|
+
// If we didn't find a match, we compare the selected link to the href of each nav item
|
177
|
+
const selectedNavItem = this.querySelector<HTMLAnchorElement>(`.ActionListContent[href="${href}"]`)
|
178
|
+
if (selectedNavItem) {
|
179
|
+
return selectedNavItem.closest('.ActionListItem')
|
180
|
+
}
|
181
|
+
|
182
|
+
return null
|
183
|
+
}
|
184
|
+
|
185
|
+
#findSelectedNavItemByCurrentLocation(): HTMLElement | null {
|
186
|
+
return this.#findSelectedNavItemByHref(window.location.pathname)
|
187
|
+
}
|
188
|
+
|
189
|
+
#select(navItem: HTMLElement) {
|
190
|
+
const currentlySelectedItem = this.querySelector('.ActionListItem--navActive') as HTMLElement
|
191
|
+
if (currentlySelectedItem) this.#deselect(currentlySelectedItem)
|
192
|
+
|
193
|
+
navItem.classList.add('ActionListItem--navActive')
|
194
|
+
|
195
|
+
const parentMenu = this.#findParentMenu(navItem)
|
196
|
+
|
197
|
+
if (parentMenu) {
|
198
|
+
this.expandItem(parentMenu)
|
199
|
+
parentMenu.classList.add('ActionListContent--hasActiveSubItem')
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
#deselect(navItem: HTMLElement) {
|
204
|
+
navItem.classList.remove('ActionListItem--navActive')
|
205
|
+
|
206
|
+
const parentMenu = this.#findParentMenu(navItem)
|
207
|
+
|
208
|
+
if (parentMenu) {
|
209
|
+
this.collapseItem(parentMenu)
|
210
|
+
parentMenu.classList.remove('ActionListContent--hasActiveSubItem')
|
211
|
+
}
|
212
|
+
}
|
213
|
+
|
214
|
+
#findParentMenu(navItem: HTMLElement): HTMLElement | null {
|
215
|
+
if (!navItem.classList.contains('ActionListItem--subItem')) return null
|
216
|
+
|
217
|
+
const parent = navItem.closest('li.ActionListItem--hasSubItem')?.querySelector('button.ActionListContent')
|
218
|
+
|
219
|
+
if (parent) {
|
220
|
+
return parent as HTMLElement
|
221
|
+
} else {
|
222
|
+
return null
|
223
|
+
}
|
224
|
+
}
|
123
225
|
}
|
124
226
|
|
125
227
|
declare global {
|