primer_view_components 0.43.5 → 0.44.0

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.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/app/assets/javascripts/components/primer/alpha/tree_view/tree_view.d.ts +39 -0
  4. data/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_icon_pair_element.d.ts +15 -0
  5. data/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_include_fragment_element.d.ts +9 -0
  6. data/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_roving_tab_index.d.ts +3 -0
  7. data/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.d.ts +42 -0
  8. data/app/assets/javascripts/components/primer/primer.d.ts +4 -0
  9. data/app/assets/javascripts/components/primer/shared_events.d.ts +15 -0
  10. data/app/assets/javascripts/primer_view_components.js +1 -1
  11. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  12. data/app/assets/styles/primer_view_components.css +1 -1
  13. data/app/assets/styles/primer_view_components.css.map +1 -1
  14. data/app/components/primer/alpha/file_tree_view/directory_node.html.erb +5 -0
  15. data/app/components/primer/alpha/file_tree_view/directory_node.rb +24 -0
  16. data/app/components/primer/alpha/file_tree_view/file_node.html.erb +2 -0
  17. data/app/components/primer/alpha/file_tree_view/file_node.rb +14 -0
  18. data/app/components/primer/alpha/file_tree_view.rb +15 -0
  19. data/app/components/primer/alpha/skeleton_box.css +1 -0
  20. data/app/components/primer/alpha/skeleton_box.css.json +6 -0
  21. data/app/components/primer/alpha/skeleton_box.css.map +1 -0
  22. data/app/components/primer/alpha/skeleton_box.html.erb +1 -0
  23. data/app/components/primer/alpha/skeleton_box.pcss +30 -0
  24. data/app/components/primer/alpha/skeleton_box.rb +29 -0
  25. data/app/components/primer/alpha/tree_view/icon.html.erb +1 -0
  26. data/app/components/primer/alpha/tree_view/icon.rb +22 -0
  27. data/app/components/primer/alpha/tree_view/icon_pair.html.erb +13 -0
  28. data/app/components/primer/alpha/tree_view/icon_pair.rb +42 -0
  29. data/app/components/primer/alpha/tree_view/leading_action.html.erb +3 -0
  30. data/app/components/primer/alpha/tree_view/leading_action.rb +18 -0
  31. data/app/components/primer/alpha/tree_view/leaf_node.html.erb +18 -0
  32. data/app/components/primer/alpha/tree_view/leaf_node.rb +96 -0
  33. data/app/components/primer/alpha/tree_view/loading_failure_message.html.erb +13 -0
  34. data/app/components/primer/alpha/tree_view/loading_failure_message.rb +31 -0
  35. data/app/components/primer/alpha/tree_view/node.html.erb +32 -0
  36. data/app/components/primer/alpha/tree_view/node.rb +194 -0
  37. data/app/components/primer/alpha/tree_view/skeleton_loader.html.erb +23 -0
  38. data/app/components/primer/alpha/tree_view/skeleton_loader.rb +36 -0
  39. data/app/components/primer/alpha/tree_view/spinner_loader.html.erb +20 -0
  40. data/app/components/primer/alpha/tree_view/spinner_loader.rb +33 -0
  41. data/app/components/primer/alpha/tree_view/sub_tree.html.erb +21 -0
  42. data/app/components/primer/alpha/tree_view/sub_tree.rb +113 -0
  43. data/app/components/primer/alpha/tree_view/sub_tree_container.html.erb +3 -0
  44. data/app/components/primer/alpha/tree_view/sub_tree_container.rb +39 -0
  45. data/app/components/primer/alpha/tree_view/sub_tree_node.html.erb +49 -0
  46. data/app/components/primer/alpha/tree_view/sub_tree_node.rb +188 -0
  47. data/app/components/primer/alpha/tree_view/tree_view.d.ts +39 -0
  48. data/app/components/primer/alpha/tree_view/tree_view.js +363 -0
  49. data/app/components/primer/alpha/tree_view/tree_view.ts +396 -0
  50. data/app/components/primer/alpha/tree_view/tree_view_icon_pair_element.d.ts +15 -0
  51. data/app/components/primer/alpha/tree_view/tree_view_icon_pair_element.js +62 -0
  52. data/app/components/primer/alpha/tree_view/tree_view_icon_pair_element.ts +56 -0
  53. data/app/components/primer/alpha/tree_view/tree_view_include_fragment_element.d.ts +9 -0
  54. data/app/components/primer/alpha/tree_view/tree_view_include_fragment_element.js +28 -0
  55. data/app/components/primer/alpha/tree_view/tree_view_include_fragment_element.ts +28 -0
  56. data/app/components/primer/alpha/tree_view/tree_view_roving_tab_index.d.ts +3 -0
  57. data/app/components/primer/alpha/tree_view/tree_view_roving_tab_index.js +130 -0
  58. data/app/components/primer/alpha/tree_view/tree_view_roving_tab_index.ts +161 -0
  59. data/app/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.d.ts +42 -0
  60. data/app/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.js +418 -0
  61. data/app/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.ts +470 -0
  62. data/app/components/primer/alpha/tree_view/visual.html.erb +14 -0
  63. data/app/components/primer/alpha/tree_view/visual.rb +27 -0
  64. data/app/components/primer/alpha/tree_view.css +1 -0
  65. data/app/components/primer/alpha/tree_view.css.json +52 -0
  66. data/app/components/primer/alpha/tree_view.css.map +1 -0
  67. data/app/components/primer/alpha/tree_view.html.erb +12 -0
  68. data/app/components/primer/alpha/tree_view.pcss +373 -0
  69. data/app/components/primer/alpha/tree_view.rb +439 -0
  70. data/app/components/primer/beta/breadcrumbs.css +1 -1
  71. data/app/components/primer/beta/breadcrumbs.css.json +0 -1
  72. data/app/components/primer/beta/breadcrumbs.css.map +1 -1
  73. data/app/components/primer/beta/breadcrumbs.pcss +2 -8
  74. data/app/components/primer/beta/progress_bar.css +1 -1
  75. data/app/components/primer/beta/progress_bar.css.map +1 -1
  76. data/app/components/primer/beta/progress_bar.pcss +3 -2
  77. data/app/components/primer/beta/relative_time.rb +3 -0
  78. data/app/components/primer/beta/spinner.html.erb +1 -1
  79. data/app/components/primer/beta/spinner.rb +2 -0
  80. data/app/components/primer/primer.d.ts +4 -0
  81. data/app/components/primer/primer.js +4 -0
  82. data/app/components/primer/primer.pcss +2 -0
  83. data/app/components/primer/primer.ts +4 -0
  84. data/app/components/primer/shared_events.d.ts +15 -0
  85. data/app/components/primer/shared_events.ts +19 -0
  86. data/app/controllers/primer/view_components/tree_view_items.json +293 -0
  87. data/app/controllers/primer/view_components/tree_view_items_controller.rb +55 -0
  88. data/app/forms/check_box_with_nested_form.rb +10 -10
  89. data/app/forms/radio_button_with_nested_form.rb +16 -16
  90. data/app/views/primer/view_components/tree_view_items/async_alpha.html_fragment.erb +23 -0
  91. data/app/views/primer/view_components/tree_view_items/index.html_fragment.erb +24 -0
  92. data/config/routes.rb +2 -0
  93. data/lib/primer/view_components/version.rb +2 -2
  94. data/previews/primer/alpha/file_tree_view_preview/default.html.erb +16 -0
  95. data/previews/primer/alpha/file_tree_view_preview/playground.html.erb +4 -0
  96. data/previews/primer/alpha/file_tree_view_preview.rb +69 -0
  97. data/previews/primer/alpha/skeleton_box_preview.rb +20 -0
  98. data/previews/primer/alpha/tree_view_preview/async_alpha.html.erb +12 -0
  99. data/previews/primer/alpha/tree_view_preview/buttons.html.erb +10 -0
  100. data/previews/primer/alpha/tree_view_preview/default.html.erb +24 -0
  101. data/previews/primer/alpha/tree_view_preview/empty.html.erb +10 -0
  102. data/previews/primer/alpha/tree_view_preview/form_input.html.erb +14 -0
  103. data/previews/primer/alpha/tree_view_preview/leaf_node_playground.html.erb +15 -0
  104. data/previews/primer/alpha/tree_view_preview/links.html.erb +17 -0
  105. data/previews/primer/alpha/tree_view_preview/loading_failure.html.erb +36 -0
  106. data/previews/primer/alpha/tree_view_preview/loading_skeleton.html.erb +12 -0
  107. data/previews/primer/alpha/tree_view_preview/loading_spinner.html.erb +12 -0
  108. data/previews/primer/alpha/tree_view_preview/playground.html.erb +4 -0
  109. data/previews/primer/alpha/tree_view_preview.rb +208 -0
  110. data/static/arguments.json +456 -0
  111. data/static/audited_at.json +17 -0
  112. data/static/classes.json +15 -0
  113. data/static/constants.json +101 -0
  114. data/static/info_arch.json +1410 -56
  115. data/static/previews.json +232 -0
  116. data/static/statuses.json +17 -0
  117. metadata +89 -8
@@ -0,0 +1,396 @@
1
+ import {controller, target} from '@github/catalyst'
2
+ import {TreeViewSubTreeNodeElement} from './tree_view_sub_tree_node_element'
3
+ import {useRovingTabIndex} from './tree_view_roving_tab_index'
4
+ import type {TreeViewNodeType, TreeViewCheckedValue, TreeViewNodeInfo} from '../../shared_events'
5
+
6
+ @controller
7
+ export class TreeViewElement extends HTMLElement {
8
+ @target formInputContainer: HTMLElement
9
+ @target formInputPrototype: HTMLInputElement
10
+
11
+ #abortController: AbortController
12
+
13
+ connectedCallback() {
14
+ const {signal} = (this.#abortController = new AbortController())
15
+ this.addEventListener('click', this, {signal})
16
+ this.addEventListener('focusin', this, {signal})
17
+ this.addEventListener('keydown', this, {signal})
18
+
19
+ useRovingTabIndex(this)
20
+
21
+ // catch-all for any straggler nodes that aren't available when connectedCallback runs
22
+ new MutationObserver(mutations => {
23
+ for (const mutation of mutations) {
24
+ for (const addedNode of mutation.addedNodes) {
25
+ if (!(addedNode instanceof HTMLElement)) continue
26
+
27
+ if (addedNode.querySelector('[aria-expanded=true]')) {
28
+ this.#autoExpandFrom(addedNode)
29
+ }
30
+ }
31
+ }
32
+ }).observe(this, {childList: true, subtree: true})
33
+
34
+ const updateInputsObserver = new MutationObserver(mutations => {
35
+ if (!this.formInputContainer) return
36
+
37
+ // There is another MutationObserver in TreeViewSubTreeNodeElement that manages checking/unchecking
38
+ // nodes based on the component's select strategy. These two observers can conflict and cause infinite
39
+ // looping, so we make sure something actually changed before computing inputs again.
40
+ const somethingChanged = mutations.some(m => {
41
+ if (!(m.target instanceof HTMLElement)) return false
42
+ return m.target.getAttribute('aria-checked') !== m.oldValue
43
+ })
44
+
45
+ if (!somethingChanged) return
46
+
47
+ const newInputs = []
48
+
49
+ for (const node of this.querySelectorAll('[role=treeitem][aria-checked=true]')) {
50
+ const newInput = this.formInputPrototype.cloneNode() as HTMLInputElement
51
+ newInput.removeAttribute('data-target')
52
+ newInput.removeAttribute('form')
53
+
54
+ const payload: {path: string[]; value?: string} = {
55
+ path: this.getNodePath(node),
56
+ }
57
+
58
+ const inputValue = this.getFormInputValueForNode(node)
59
+ if (inputValue) payload.value = inputValue
60
+
61
+ newInput.value = JSON.stringify(payload)
62
+ newInputs.push(newInput)
63
+ }
64
+
65
+ this.formInputContainer.replaceChildren(...newInputs)
66
+ })
67
+
68
+ updateInputsObserver.observe(this, {
69
+ childList: true,
70
+ subtree: true,
71
+ attributeFilter: ['aria-checked'],
72
+ })
73
+
74
+ // eslint-disable-next-line github/no-then -- We don't want to wait for this to resolve, just get on with it
75
+ customElements.whenDefined('tree-view-sub-tree-node').then(() => {
76
+ // depends on TreeViewSubTreeNodeElement#eachAncestorSubTreeNode, which may not be defined yet
77
+ this.#autoExpandFrom(this)
78
+ })
79
+ }
80
+
81
+ #autoExpandFrom(root: HTMLElement) {
82
+ for (const element of root.querySelectorAll('[aria-expanded=true]')) {
83
+ this.expandAncestorsForNode(element as HTMLElement)
84
+ }
85
+ }
86
+
87
+ disconnectedCallback() {
88
+ this.#abortController.abort()
89
+ }
90
+
91
+ handleEvent(event: Event) {
92
+ const node = this.#nodeForEvent(event)
93
+
94
+ if (node) {
95
+ this.#handleNodeEvent(node, event)
96
+ }
97
+ }
98
+
99
+ #eventIsActivation(event: Event): boolean {
100
+ return event.type === 'click'
101
+ }
102
+
103
+ #nodeForEvent(event: Event): Element | null {
104
+ const eventTarget = event.target as Element
105
+ const node = eventTarget.closest('[role=treeitem]')
106
+ if (!node) return null
107
+
108
+ if (eventTarget.closest('.TreeViewItemToggle')) return null
109
+ if (eventTarget.closest('.TreeViewItemLeadingAction')) return null
110
+
111
+ return node
112
+ }
113
+
114
+ #handleNodeEvent(node: Element, event: Event) {
115
+ if (this.#eventIsCheckboxToggle(event, node)) {
116
+ this.#handleCheckboxToggle(event, node)
117
+ } else if (this.#eventIsActivation(event)) {
118
+ this.#handleNodeActivated(event, node)
119
+ } else if (event.type === 'focusin') {
120
+ this.#handleNodeFocused(node)
121
+ } else if (event instanceof KeyboardEvent) {
122
+ this.#handleNodeKeyboardEvent(event, node)
123
+ }
124
+ }
125
+
126
+ #eventIsCheckboxToggle(event: Event, node: Element) {
127
+ return event.type === 'click' && this.nodeHasCheckBox(node)
128
+ }
129
+
130
+ #handleCheckboxToggle(event: Event, node: Element) {
131
+ if (this.getNodeDisabledValue(node)) {
132
+ event.preventDefault()
133
+ return
134
+ }
135
+
136
+ // only handle checking of leaf nodes, see TreeViewSubTreeNodeElement for the code that
137
+ // handles checking sub tree items.
138
+ const type = this.getNodeType(node)
139
+ if (type !== 'leaf') return
140
+
141
+ if (this.getNodeCheckedValue(node) === 'true') {
142
+ this.setNodeCheckedValue(node, 'false')
143
+ } else {
144
+ this.setNodeCheckedValue(node, 'true')
145
+ }
146
+ }
147
+
148
+ #handleNodeActivated(event: Event, node: Element) {
149
+ if (this.getNodeDisabledValue(node)) {
150
+ event.preventDefault()
151
+ return
152
+ }
153
+
154
+ // do not emit activation events for buttons and anchors, since it is assumed any activation
155
+ // behavior for these element types is user- or browser-defined
156
+ if (!(node instanceof HTMLDivElement)) return
157
+
158
+ const path = this.getNodePath(node)
159
+
160
+ const activationSuccess = this.dispatchEvent(
161
+ new CustomEvent('treeViewBeforeNodeActivated', {
162
+ bubbles: true,
163
+ cancelable: true,
164
+ detail: this.infoFromNode(node),
165
+ }),
166
+ )
167
+
168
+ if (!activationSuccess) return
169
+
170
+ // navigate or trigger button, don't toggle
171
+ if (!this.nodeHasNativeAction(node)) {
172
+ this.toggleAtPath(path)
173
+ }
174
+
175
+ this.dispatchEvent(
176
+ new CustomEvent('treeViewNodeActivated', {
177
+ bubbles: true,
178
+ detail: this.infoFromNode(node),
179
+ }),
180
+ )
181
+ }
182
+
183
+ #handleNodeFocused(node: Element) {
184
+ const previousNode = this.querySelector('[aria-selected=true]')
185
+ previousNode?.setAttribute('aria-selected', 'false')
186
+ node.setAttribute('aria-selected', 'true')
187
+ }
188
+
189
+ #handleNodeKeyboardEvent(event: KeyboardEvent, node: Element) {
190
+ if (!node || this.getNodeType(node) !== 'leaf') {
191
+ return
192
+ }
193
+
194
+ switch (event.key) {
195
+ case ' ':
196
+ case 'Enter':
197
+ if (this.getNodeDisabledValue(node)) {
198
+ event.preventDefault()
199
+ break
200
+ }
201
+
202
+ if (this.nodeHasCheckBox(node)) {
203
+ event.preventDefault()
204
+
205
+ if (this.getNodeCheckedValue(node) === 'true') {
206
+ this.setNodeCheckedValue(node, 'false')
207
+ } else {
208
+ this.setNodeCheckedValue(node, 'true')
209
+ }
210
+ } else if (node instanceof HTMLAnchorElement) {
211
+ // simulate click on space
212
+ node.click()
213
+ }
214
+
215
+ break
216
+ }
217
+ }
218
+
219
+ getFormInputValueForNode(node: Element): string | null {
220
+ return node.getAttribute('data-value')
221
+ }
222
+
223
+ getNodePath(node: Element): string[] {
224
+ const rawPath = node.getAttribute('data-path')
225
+
226
+ if (rawPath) {
227
+ return JSON.parse(rawPath)
228
+ }
229
+
230
+ return []
231
+ }
232
+
233
+ getNodeType(node: Element): TreeViewNodeType | null {
234
+ return node.getAttribute('data-node-type') as TreeViewNodeType | null
235
+ }
236
+
237
+ markCurrentAtPath(path: string[]) {
238
+ const pathStr = JSON.stringify(path)
239
+ const nodeToMark = this.querySelector(`[data-path="${CSS.escape(pathStr)}"`)
240
+ if (!nodeToMark) return
241
+
242
+ this.currentNode?.setAttribute('aria-current', 'false')
243
+ nodeToMark.setAttribute('aria-current', 'true')
244
+ }
245
+
246
+ get currentNode(): HTMLLIElement | null {
247
+ return this.querySelector('[aria-current=true]')
248
+ }
249
+
250
+ expandAtPath(path: string[]) {
251
+ const node = this.subTreeAtPath(path)
252
+ if (!node) return
253
+
254
+ node.expand()
255
+ }
256
+
257
+ collapseAtPath(path: string[]) {
258
+ const node = this.subTreeAtPath(path)
259
+ if (!node) return
260
+
261
+ node.collapse()
262
+ }
263
+
264
+ toggleAtPath(path: string[]) {
265
+ const node = this.subTreeAtPath(path)
266
+ if (!node) return
267
+
268
+ node.toggle()
269
+ }
270
+
271
+ checkAtPath(path: string[]) {
272
+ const node = this.nodeAtPath(path)
273
+ if (!node) return
274
+
275
+ this.setNodeCheckedValue(node, 'true')
276
+ }
277
+
278
+ uncheckAtPath(path: string[]) {
279
+ const node = this.nodeAtPath(path)
280
+ if (!node) return
281
+
282
+ this.setNodeCheckedValue(node, 'false')
283
+ }
284
+
285
+ toggleCheckedAtPath(path: string[]) {
286
+ const node = this.nodeAtPath(path)
287
+ if (!node) return
288
+
289
+ if (this.getNodeType(node) === 'leaf') {
290
+ if (this.getNodeCheckedValue(node) === 'true') {
291
+ this.uncheckAtPath(path)
292
+ } else {
293
+ this.checkAtPath(path)
294
+ }
295
+ }
296
+ }
297
+
298
+ checkedValueAtPath(path: string[]): TreeViewCheckedValue {
299
+ const node = this.nodeAtPath(path)
300
+ if (!node) return 'false'
301
+
302
+ return this.getNodeCheckedValue(node)
303
+ }
304
+
305
+ disabledValueAtPath(path: string[]): boolean {
306
+ const node = this.nodeAtPath(path)
307
+ if (!node) return false
308
+
309
+ return this.getNodeDisabledValue(node)
310
+ }
311
+
312
+ nodeAtPath(path: string[], selector?: string): Element | null {
313
+ const pathStr = JSON.stringify(path)
314
+ return this.querySelector(`${selector || ''}[data-path="${CSS.escape(pathStr)}"]`)
315
+ }
316
+
317
+ subTreeAtPath(path: string[]): TreeViewSubTreeNodeElement | null {
318
+ const node = this.nodeAtPath(path, '[data-node-type=sub-tree]')
319
+ if (!node) return null
320
+
321
+ return node.closest('tree-view-sub-tree-node') as TreeViewSubTreeNodeElement | null
322
+ }
323
+
324
+ leafAtPath(path: string[]): HTMLLIElement | null {
325
+ return this.nodeAtPath(path, '[data-node-type=leaf]') as HTMLLIElement | null
326
+ }
327
+
328
+ setNodeCheckedValue(node: Element, value: TreeViewCheckedValue) {
329
+ node.setAttribute('aria-checked', value.toString())
330
+ }
331
+
332
+ getNodeCheckedValue(node: Element): TreeViewCheckedValue {
333
+ return (node.getAttribute('aria-checked') || 'false') as TreeViewCheckedValue
334
+ }
335
+
336
+ getNodeDisabledValue(node: Element): boolean {
337
+ return node.getAttribute('aria-disabled') === 'true'
338
+ }
339
+
340
+ setNodeDisabledValue(node: Element, disabled: boolean) {
341
+ if (disabled) {
342
+ node.setAttribute('aria-disabled', 'true')
343
+ } else {
344
+ node.removeAttribute('aria-disabled')
345
+ }
346
+ }
347
+
348
+ nodeHasCheckBox(node: Element): boolean {
349
+ return node.querySelector('.TreeViewItemCheckbox') !== null
350
+ }
351
+
352
+ nodeHasNativeAction(node: Element): boolean {
353
+ return node instanceof HTMLAnchorElement || node instanceof HTMLButtonElement
354
+ }
355
+
356
+ expandAncestorsForNode(node: HTMLElement) {
357
+ const subTreeNode = node.closest('tree-view-sub-tree-node') as TreeViewSubTreeNodeElement
358
+ if (!subTreeNode) return
359
+
360
+ for (const ancestor of subTreeNode.eachAncestorSubTreeNode()) {
361
+ if (!ancestor.expanded) {
362
+ ancestor.expand()
363
+ }
364
+ }
365
+ }
366
+
367
+ // PRIVATE API METHOD
368
+ //
369
+ // This would normally be marked private, but it's called by TreeViewSubTreeNodes
370
+ // and thus must be public.
371
+ infoFromNode(node: Element, newCheckedValue?: TreeViewCheckedValue): TreeViewNodeInfo | null {
372
+ const type = this.getNodeType(node)
373
+ if (!type) return null
374
+
375
+ const checkedValue = this.getNodeCheckedValue(node)
376
+
377
+ return {
378
+ node,
379
+ type,
380
+ path: this.getNodePath(node),
381
+ checkedValue: newCheckedValue || checkedValue,
382
+ previousCheckedValue: checkedValue,
383
+ }
384
+ }
385
+ }
386
+
387
+ if (!window.customElements.get('tree-view')) {
388
+ window.TreeViewElement = TreeViewElement
389
+ window.customElements.define('tree-view', TreeViewElement)
390
+ }
391
+
392
+ declare global {
393
+ interface Window {
394
+ TreeViewElement: typeof TreeViewElement
395
+ }
396
+ }
@@ -0,0 +1,15 @@
1
+ export declare class TreeViewIconPairElement extends HTMLElement {
2
+ #private;
3
+ expandedIcon: HTMLElement;
4
+ collapsedIcon: HTMLElement;
5
+ expanded: boolean;
6
+ connectedCallback(): void;
7
+ showExpanded(): void;
8
+ showCollapsed(): void;
9
+ toggle(): void;
10
+ }
11
+ declare global {
12
+ interface Window {
13
+ TreeViewIconPairElement: typeof TreeViewIconPairElement;
14
+ }
15
+ }
@@ -0,0 +1,62 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
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 _TreeViewIconPairElement_instances, _TreeViewIconPairElement_update;
13
+ import { controller, target } from '@github/catalyst';
14
+ import { observeMutationsUntilConditionMet } from '../../utils';
15
+ let TreeViewIconPairElement = class TreeViewIconPairElement extends HTMLElement {
16
+ constructor() {
17
+ super(...arguments);
18
+ _TreeViewIconPairElement_instances.add(this);
19
+ }
20
+ connectedCallback() {
21
+ observeMutationsUntilConditionMet(this, () => Boolean(this.collapsedIcon) && Boolean(this.expandedIcon), () => {
22
+ this.expanded = this.collapsedIcon.hidden;
23
+ });
24
+ }
25
+ showExpanded() {
26
+ this.expanded = true;
27
+ __classPrivateFieldGet(this, _TreeViewIconPairElement_instances, "m", _TreeViewIconPairElement_update).call(this);
28
+ }
29
+ showCollapsed() {
30
+ this.expanded = false;
31
+ __classPrivateFieldGet(this, _TreeViewIconPairElement_instances, "m", _TreeViewIconPairElement_update).call(this);
32
+ }
33
+ toggle() {
34
+ this.expanded = !this.expanded;
35
+ __classPrivateFieldGet(this, _TreeViewIconPairElement_instances, "m", _TreeViewIconPairElement_update).call(this);
36
+ }
37
+ };
38
+ _TreeViewIconPairElement_instances = new WeakSet();
39
+ _TreeViewIconPairElement_update = function _TreeViewIconPairElement_update() {
40
+ if (this.expanded) {
41
+ this.expandedIcon.hidden = false;
42
+ this.collapsedIcon.hidden = true;
43
+ }
44
+ else {
45
+ this.expandedIcon.hidden = true;
46
+ this.collapsedIcon.hidden = false;
47
+ }
48
+ };
49
+ __decorate([
50
+ target
51
+ ], TreeViewIconPairElement.prototype, "expandedIcon", void 0);
52
+ __decorate([
53
+ target
54
+ ], TreeViewIconPairElement.prototype, "collapsedIcon", void 0);
55
+ TreeViewIconPairElement = __decorate([
56
+ controller
57
+ ], TreeViewIconPairElement);
58
+ export { TreeViewIconPairElement };
59
+ if (!window.customElements.get('tree-view-icon-pair')) {
60
+ window.TreeViewIconPairElement = TreeViewIconPairElement;
61
+ window.customElements.define('tree-view-icon-pair', TreeViewIconPairElement);
62
+ }
@@ -0,0 +1,56 @@
1
+ import {controller, target} from '@github/catalyst'
2
+ import {observeMutationsUntilConditionMet} from '../../utils'
3
+
4
+ @controller
5
+ export class TreeViewIconPairElement extends HTMLElement {
6
+ @target expandedIcon: HTMLElement
7
+ @target collapsedIcon: HTMLElement
8
+
9
+ expanded: boolean
10
+
11
+ connectedCallback() {
12
+ observeMutationsUntilConditionMet(
13
+ this,
14
+ () => Boolean(this.collapsedIcon) && Boolean(this.expandedIcon),
15
+ () => {
16
+ this.expanded = this.collapsedIcon.hidden
17
+ },
18
+ )
19
+ }
20
+
21
+ showExpanded() {
22
+ this.expanded = true
23
+ this.#update()
24
+ }
25
+
26
+ showCollapsed() {
27
+ this.expanded = false
28
+ this.#update()
29
+ }
30
+
31
+ toggle() {
32
+ this.expanded = !this.expanded
33
+ this.#update()
34
+ }
35
+
36
+ #update() {
37
+ if (this.expanded) {
38
+ this.expandedIcon.hidden = false
39
+ this.collapsedIcon.hidden = true
40
+ } else {
41
+ this.expandedIcon.hidden = true
42
+ this.collapsedIcon.hidden = false
43
+ }
44
+ }
45
+ }
46
+
47
+ if (!window.customElements.get('tree-view-icon-pair')) {
48
+ window.TreeViewIconPairElement = TreeViewIconPairElement
49
+ window.customElements.define('tree-view-icon-pair', TreeViewIconPairElement)
50
+ }
51
+
52
+ declare global {
53
+ interface Window {
54
+ TreeViewIconPairElement: typeof TreeViewIconPairElement
55
+ }
56
+ }
@@ -0,0 +1,9 @@
1
+ import { IncludeFragmentElement } from '@github/include-fragment-element';
2
+ export declare class TreeViewIncludeFragmentElement extends IncludeFragmentElement {
3
+ request(): Request;
4
+ }
5
+ declare global {
6
+ interface Window {
7
+ TreeViewIncludeFragmentElement: typeof TreeViewIncludeFragmentElement;
8
+ }
9
+ }
@@ -0,0 +1,28 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { controller } from '@github/catalyst';
8
+ import { IncludeFragmentElement } from '@github/include-fragment-element';
9
+ let TreeViewIncludeFragmentElement = class TreeViewIncludeFragmentElement extends IncludeFragmentElement {
10
+ request() {
11
+ const originalRequest = super.request();
12
+ const url = new URL(originalRequest.url);
13
+ url.searchParams.set('path', this.getAttribute('data-path') || '');
14
+ return new Request(url, {
15
+ method: originalRequest.method,
16
+ headers: originalRequest.headers,
17
+ credentials: originalRequest.credentials,
18
+ });
19
+ }
20
+ };
21
+ TreeViewIncludeFragmentElement = __decorate([
22
+ controller
23
+ ], TreeViewIncludeFragmentElement);
24
+ export { TreeViewIncludeFragmentElement };
25
+ if (!window.customElements.get('tree-view-include-fragment')) {
26
+ window.TreeViewIncludeFragmentElement = TreeViewIncludeFragmentElement;
27
+ window.customElements.define('tree-view-include-fragment', TreeViewIncludeFragmentElement);
28
+ }
@@ -0,0 +1,28 @@
1
+ import {controller} from '@github/catalyst'
2
+ import {IncludeFragmentElement} from '@github/include-fragment-element'
3
+
4
+ @controller
5
+ export class TreeViewIncludeFragmentElement extends IncludeFragmentElement {
6
+ request(): Request {
7
+ const originalRequest = super.request()
8
+ const url = new URL(originalRequest.url)
9
+ url.searchParams.set('path', this.getAttribute('data-path') || '')
10
+
11
+ return new Request(url, {
12
+ method: originalRequest.method,
13
+ headers: originalRequest.headers,
14
+ credentials: originalRequest.credentials,
15
+ })
16
+ }
17
+ }
18
+
19
+ if (!window.customElements.get('tree-view-include-fragment')) {
20
+ window.TreeViewIncludeFragmentElement = TreeViewIncludeFragmentElement
21
+ window.customElements.define('tree-view-include-fragment', TreeViewIncludeFragmentElement)
22
+ }
23
+
24
+ declare global {
25
+ interface Window {
26
+ TreeViewIncludeFragmentElement: typeof TreeViewIncludeFragmentElement
27
+ }
28
+ }
@@ -0,0 +1,3 @@
1
+ import { TreeViewElement } from './tree_view';
2
+ export declare function useRovingTabIndex(containerEl: TreeViewElement): void;
3
+ export declare function getElementState(element: HTMLElement): 'open' | 'closed' | 'end';