openproject-primer_view_components 0.70.5 → 0.72.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 (142) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/app/assets/javascripts/components/primer/alpha/segmented_control.d.ts +2 -2
  4. data/app/assets/javascripts/components/primer/{open_project → alpha}/tree_view/tree_view.d.ts +11 -1
  5. data/app/assets/javascripts/components/primer/{open_project → alpha}/tree_view/tree_view_sub_tree_node_element.d.ts +5 -1
  6. data/app/assets/javascripts/components/primer/open_project/filterable_tree_view.d.ts +29 -0
  7. data/app/assets/javascripts/components/primer/primer.d.ts +5 -4
  8. data/app/assets/javascripts/primer_view_components.js +1 -1
  9. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  10. data/app/assets/styles/primer_view_components.css +1 -1
  11. data/app/assets/styles/primer_view_components.css.map +1 -1
  12. data/app/components/primer/{open_project → alpha}/file_tree_view/directory_node.rb +1 -1
  13. data/app/components/primer/{open_project → alpha}/file_tree_view/file_node.rb +1 -1
  14. data/app/components/primer/{open_project → alpha}/file_tree_view.rb +1 -1
  15. data/app/components/primer/alpha/segmented_control.d.ts +2 -2
  16. data/app/components/primer/alpha/segmented_control.js +12 -0
  17. data/app/components/primer/alpha/segmented_control.ts +16 -1
  18. data/app/components/primer/{open_project → alpha}/skeleton_box.css.json +1 -1
  19. data/app/components/primer/{open_project → alpha}/skeleton_box.css.map +1 -1
  20. data/app/components/primer/{open_project → alpha}/skeleton_box.pcss +1 -1
  21. data/app/components/primer/{open_project → alpha}/skeleton_box.rb +3 -1
  22. data/app/components/primer/alpha/stack.css +1 -1
  23. data/app/components/primer/alpha/stack.css.json +5 -1
  24. data/app/components/primer/alpha/stack.css.map +1 -1
  25. data/app/components/primer/alpha/stack.pcss +13 -0
  26. data/app/components/primer/alpha/stack.rb +2 -1
  27. data/app/components/primer/{open_project → alpha}/tree_view/icon.rb +2 -2
  28. data/app/components/primer/{open_project → alpha}/tree_view/icon_pair.rb +4 -4
  29. data/app/components/primer/{open_project → alpha}/tree_view/leading_action.rb +2 -2
  30. data/app/components/primer/{open_project → alpha}/tree_view/leaf_node.rb +6 -6
  31. data/app/components/primer/{open_project → alpha}/tree_view/loading_failure_message.rb +2 -2
  32. data/app/components/primer/{open_project → alpha}/tree_view/node.rb +30 -14
  33. data/app/components/primer/{open_project → alpha}/tree_view/skeleton_loader.html.erb +3 -3
  34. data/app/components/primer/{open_project → alpha}/tree_view/skeleton_loader.rb +4 -4
  35. data/app/components/primer/{open_project → alpha}/tree_view/spinner_loader.html.erb +2 -2
  36. data/app/components/primer/{open_project → alpha}/tree_view/spinner_loader.rb +4 -4
  37. data/app/components/primer/{open_project → alpha}/tree_view/sub_tree.html.erb +1 -1
  38. data/app/components/primer/{open_project → alpha}/tree_view/sub_tree.rb +10 -10
  39. data/app/components/primer/{open_project → alpha}/tree_view/sub_tree_container.rb +2 -2
  40. data/app/components/primer/{open_project → alpha}/tree_view/sub_tree_node.rb +28 -18
  41. data/app/components/primer/{open_project → alpha}/tree_view/tree_view.d.ts +11 -1
  42. data/app/components/primer/{open_project → alpha}/tree_view/tree_view.js +120 -20
  43. data/app/components/primer/{open_project → alpha}/tree_view/tree_view.ts +137 -18
  44. data/app/components/primer/{open_project → alpha}/tree_view/tree_view_include_fragment_element.js +0 -1
  45. data/app/components/primer/{open_project → alpha}/tree_view/tree_view_include_fragment_element.ts +0 -1
  46. data/app/components/primer/{open_project → alpha}/tree_view/tree_view_sub_tree_node_element.d.ts +5 -1
  47. data/app/components/primer/{open_project → alpha}/tree_view/tree_view_sub_tree_node_element.js +27 -4
  48. data/app/components/primer/{open_project → alpha}/tree_view/tree_view_sub_tree_node_element.ts +36 -5
  49. data/app/components/primer/{open_project → alpha}/tree_view/visual.rb +2 -2
  50. data/app/components/primer/alpha/tree_view.css +1 -0
  51. data/app/components/primer/{open_project → alpha}/tree_view.css.json +8 -1
  52. data/app/components/primer/alpha/tree_view.css.map +1 -0
  53. data/app/components/primer/alpha/tree_view.html.erb +12 -0
  54. data/app/components/primer/{open_project → alpha}/tree_view.pcss +39 -0
  55. data/app/components/primer/{open_project → alpha}/tree_view.rb +20 -12
  56. data/app/components/primer/beta/breadcrumbs.css +1 -1
  57. data/app/components/primer/beta/breadcrumbs.css.json +0 -1
  58. data/app/components/primer/beta/breadcrumbs.css.map +1 -1
  59. data/app/components/primer/beta/breadcrumbs.pcss +2 -8
  60. data/app/components/primer/beta/progress_bar.css +1 -1
  61. data/app/components/primer/beta/progress_bar.css.map +1 -1
  62. data/app/components/primer/beta/progress_bar.pcss +3 -2
  63. data/app/components/primer/beta/relative_time.rb +3 -0
  64. data/app/components/primer/open_project/filterable_tree_view/sub_tree.rb +39 -0
  65. data/app/components/primer/open_project/filterable_tree_view.d.ts +29 -0
  66. data/app/components/primer/open_project/filterable_tree_view.html.erb +28 -0
  67. data/app/components/primer/open_project/filterable_tree_view.js +409 -0
  68. data/app/components/primer/open_project/filterable_tree_view.rb +254 -0
  69. data/app/components/primer/open_project/filterable_tree_view.ts +492 -0
  70. data/app/components/primer/primer.d.ts +5 -4
  71. data/app/components/primer/primer.js +5 -4
  72. data/app/components/primer/primer.pcss +2 -2
  73. data/app/components/primer/primer.ts +5 -4
  74. data/app/controllers/primer/view_components/tree_view_items_controller.rb +1 -1
  75. data/app/forms/check_box_with_nested_form.rb +10 -10
  76. data/app/forms/radio_button_with_nested_form.rb +16 -16
  77. data/app/lib/primer/experimental_slot_helpers.rb +2 -2
  78. data/app/lib/primer/forms/base_component.rb +1 -1
  79. data/app/lib/primer/forms/dsl/text_field_input.rb +2 -0
  80. data/app/views/primer/view_components/tree_view_items/async_alpha.html_fragment.erb +1 -1
  81. data/app/views/primer/view_components/tree_view_items/index.html_fragment.erb +1 -1
  82. data/config/locales/en.yml +20 -0
  83. data/lib/primer/view_components/version.rb +2 -2
  84. data/previews/primer/{open_project → alpha}/file_tree_view_preview/default.html.erb +1 -1
  85. data/previews/primer/{open_project → alpha}/file_tree_view_preview/playground.html.erb +1 -1
  86. data/previews/primer/{open_project → alpha}/file_tree_view_preview.rb +1 -1
  87. data/previews/primer/{open_project → alpha}/skeleton_box_preview.rb +3 -3
  88. data/previews/primer/{open_project → alpha}/tree_view_preview/async_alpha.html.erb +1 -1
  89. data/previews/primer/{open_project → alpha}/tree_view_preview/buttons.html.erb +5 -5
  90. data/previews/primer/{open_project → alpha}/tree_view_preview/default.html.erb +5 -5
  91. data/previews/primer/{open_project → alpha}/tree_view_preview/empty.html.erb +1 -1
  92. data/previews/primer/alpha/tree_view_preview/form_input.html.erb +14 -0
  93. data/previews/primer/{open_project → alpha}/tree_view_preview/leaf_node_playground.html.erb +2 -2
  94. data/previews/primer/{open_project → alpha}/tree_view_preview/links.html.erb +5 -5
  95. data/previews/primer/{open_project → alpha}/tree_view_preview/loading_failure.html.erb +1 -1
  96. data/previews/primer/{open_project → alpha}/tree_view_preview/loading_skeleton.html.erb +1 -1
  97. data/previews/primer/{open_project → alpha}/tree_view_preview/loading_spinner.html.erb +1 -1
  98. data/previews/primer/{open_project → alpha}/tree_view_preview/playground.html.erb +1 -1
  99. data/previews/primer/{open_project → alpha}/tree_view_preview.rb +34 -15
  100. data/previews/primer/open_project/filterable_tree_view_preview/_custom_select_js.html.erb +62 -0
  101. data/previews/primer/open_project/filterable_tree_view_preview/custom_checkbox_text.html.erb +26 -0
  102. data/previews/primer/open_project/filterable_tree_view_preview/custom_no_results_text.html.erb +28 -0
  103. data/previews/primer/open_project/filterable_tree_view_preview/custom_segmented_control.html.erb +31 -0
  104. data/previews/primer/open_project/filterable_tree_view_preview/default.html.erb +26 -0
  105. data/previews/primer/open_project/filterable_tree_view_preview/form_input.html.erb +32 -0
  106. data/previews/primer/open_project/filterable_tree_view_preview/playground.html.erb +26 -0
  107. data/previews/primer/open_project/filterable_tree_view_preview/stress_test.html.erb +28 -0
  108. data/previews/primer/open_project/filterable_tree_view_preview.rb +125 -0
  109. data/static/arguments.json +1685 -1581
  110. data/static/audited_at.json +19 -17
  111. data/static/classes.json +5 -5
  112. data/static/constants.json +137 -98
  113. data/static/info_arch.json +6396 -6146
  114. data/static/previews.json +120 -21
  115. data/static/statuses.json +19 -17
  116. metadata +102 -84
  117. data/app/components/primer/open_project/tree_view.css +0 -1
  118. data/app/components/primer/open_project/tree_view.css.map +0 -1
  119. data/app/components/primer/open_project/tree_view.html.erb +0 -7
  120. /data/app/assets/javascripts/components/primer/{open_project → alpha}/tree_view/tree_view_icon_pair_element.d.ts +0 -0
  121. /data/app/assets/javascripts/components/primer/{open_project → alpha}/tree_view/tree_view_include_fragment_element.d.ts +0 -0
  122. /data/app/assets/javascripts/components/primer/{open_project → alpha}/tree_view/tree_view_roving_tab_index.d.ts +0 -0
  123. /data/app/components/primer/{open_project → alpha}/file_tree_view/directory_node.html.erb +0 -0
  124. /data/app/components/primer/{open_project → alpha}/file_tree_view/file_node.html.erb +0 -0
  125. /data/app/components/primer/{open_project → alpha}/skeleton_box.css +0 -0
  126. /data/app/components/primer/{open_project → alpha}/skeleton_box.html.erb +0 -0
  127. /data/app/components/primer/{open_project → alpha}/tree_view/icon.html.erb +0 -0
  128. /data/app/components/primer/{open_project → alpha}/tree_view/icon_pair.html.erb +0 -0
  129. /data/app/components/primer/{open_project → alpha}/tree_view/leading_action.html.erb +0 -0
  130. /data/app/components/primer/{open_project → alpha}/tree_view/leaf_node.html.erb +0 -0
  131. /data/app/components/primer/{open_project → alpha}/tree_view/loading_failure_message.html.erb +0 -0
  132. /data/app/components/primer/{open_project → alpha}/tree_view/node.html.erb +0 -0
  133. /data/app/components/primer/{open_project → alpha}/tree_view/sub_tree_container.html.erb +0 -0
  134. /data/app/components/primer/{open_project → alpha}/tree_view/sub_tree_node.html.erb +0 -0
  135. /data/app/components/primer/{open_project → alpha}/tree_view/tree_view_icon_pair_element.d.ts +0 -0
  136. /data/app/components/primer/{open_project → alpha}/tree_view/tree_view_icon_pair_element.js +0 -0
  137. /data/app/components/primer/{open_project → alpha}/tree_view/tree_view_icon_pair_element.ts +0 -0
  138. /data/app/components/primer/{open_project → alpha}/tree_view/tree_view_include_fragment_element.d.ts +0 -0
  139. /data/app/components/primer/{open_project → alpha}/tree_view/tree_view_roving_tab_index.d.ts +0 -0
  140. /data/app/components/primer/{open_project → alpha}/tree_view/tree_view_roving_tab_index.js +0 -0
  141. /data/app/components/primer/{open_project → alpha}/tree_view/tree_view_roving_tab_index.ts +0 -0
  142. /data/app/components/primer/{open_project → alpha}/tree_view/visual.html.erb +0 -0
@@ -1,26 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- module OpenProject
4
+ module Alpha
5
5
  class TreeView
6
6
  # A `TreeView` sub-tree.
7
7
  #
8
- # This component is part of the <%= link_to_component(Primer::OpenProject::TreeView) %> component and should
8
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
9
9
  # not be used directly.
10
10
  class SubTree < Primer::Component
11
11
  # @!parse
12
12
  # # Adds an leaf node to the tree. Leaf nodes are nodes that do not have children.
13
13
  # #
14
- # # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::OpenProject::TreeView::LeafNode) %>
15
- # # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::OpenProject::TreeView::LeafNode) %>, or whatever class is passed as the `component_klass` argument.
14
+ # # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::TreeView::LeafNode) %>
15
+ # # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::TreeView::LeafNode) %>, or whatever class is passed as the `component_klass` argument.
16
16
  # def with_leaf(**system_arguments, &block)
17
17
  # end
18
18
 
19
19
  # @!parse
20
20
  # # Adds a sub-tree node to the tree. Sub-trees are nodes that have children, which can be both leaf nodes and other sub-trees.
21
21
  # #
22
- # # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::OpenProject::TreeView::SubTreeNode) %>
23
- # # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::OpenProject::TreeView::SubTreeNode) %>, or whatever class is passed as the `component_klass` argument.
22
+ # # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::TreeView::SubTreeNode) %>
23
+ # # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::TreeView::SubTreeNode) %>, or whatever class is passed as the `component_klass` argument.
24
24
  # def with_sub_tree(**system_arguments, &block)
25
25
  # end
26
26
 
@@ -55,14 +55,14 @@ module Primer
55
55
  # @!parse
56
56
  # # Adds a loader to this sub-tree that displays a spinner animation while nodes are fetched from the server.
57
57
  # #
58
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::SpinnerLoader) %>.
58
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::SpinnerLoader) %>.
59
59
  # def with_loading_spinner(**system_arguments, &block)
60
60
  # end
61
61
 
62
62
  # @!parse
63
63
  # # Adds a loader to this sub-tree that displays a skeleton animation while nodes are fetched from the server.
64
64
  # #
65
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::SkeletonLoader) %>.
65
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::SkeletonLoader) %>.
66
66
  # def with_loading_spinner(**system_arguments, &block)
67
67
  # end
68
68
 
@@ -91,8 +91,8 @@ module Primer
91
91
 
92
92
  attr_reader :node_variant
93
93
 
94
- # @param node_variant [Symbol] The variant to use for this node. <%= one_of(Primer::OpenProject::TreeView::NODE_VARIANT_OPTIONS) %>
95
- # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::SubTreeContainer) %>.
94
+ # @param node_variant [Symbol] The variant to use for this node. <%= one_of(Primer::Alpha::TreeView::NODE_VARIANT_OPTIONS) %>
95
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::SubTreeContainer) %>.
96
96
  def initialize(node_variant:, **system_arguments)
97
97
  @node_variant = node_variant
98
98
 
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- module OpenProject
4
+ module Alpha
5
5
  class TreeView
6
- # This component is part of the <%= link_to_component(Primer::OpenProject::TreeView) %> component and should
6
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
7
7
  # not be used directly.
8
8
  class SubTreeContainer < Primer::Component
9
9
  # The path to this node
@@ -1,24 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
- module OpenProject
4
+ module Alpha
5
5
  class TreeView
6
6
  # A `TreeView` sub-tree node.
7
7
  #
8
- # This component is part of the <%= link_to_component(Primer::OpenProject::TreeView) %> component and should
8
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
9
9
  # not be used directly.
10
10
  class SubTreeNode < Primer::Component
11
- DEFAULT_SELECT_STRATEGY = :descendants
11
+ DEFAULT_SELECT_STRATEGY = :mixed_descendants
12
12
  SELECT_STRATEGIES = [
13
13
  :self,
14
- DEFAULT_SELECT_STRATEGY
14
+ DEFAULT_SELECT_STRATEGY,
15
+ :descendants
15
16
  ]
16
17
 
17
18
  # @!parse
18
19
  # # Adds a leading visual icon rendered to the left of the node's label.
19
20
  # #
20
21
  # # @param label [String] A label describing the visual, displayed only to screen readers.
21
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::Icon) %>.
22
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::Icon) %>.
22
23
  # def with_leading_visual_icon(label: nil, **system_arguments, &block)
23
24
  # end
24
25
 
@@ -26,7 +27,7 @@ module Primer
26
27
  # # Adds a pair of leading visual icon rendered to the left of the node's label.
27
28
  # #
28
29
  # # @param label [String] A label describing the visual, displayed only to screen readers.
29
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::IconPair) %>.
30
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::IconPair) %>.
30
31
  # def with_leading_visual_icons(label: nil, **system_arguments, &block)
31
32
  # end
32
33
 
@@ -59,7 +60,7 @@ module Primer
59
60
  visual: IconPair.new(
60
61
  **system_arguments,
61
62
  expanded: @sub_tree.expanded?,
62
- )
63
+ )
63
64
  )
64
65
  }
65
66
  }
@@ -86,7 +87,7 @@ module Primer
86
87
  # # Adds a trailing visual icon rendered to the right of the node's label.
87
88
  # #
88
89
  # # @param label [String] A label describing the visual, displayed only to screen readers.
89
- # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::Icon) %>.
90
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::Icon) %>.
90
91
  # def with_trailing_visual_icon(label: nil, **system_arguments, &block)
91
92
  # end
92
93
 
@@ -107,11 +108,20 @@ module Primer
107
108
 
108
109
  # @param label [String] The node's label, i.e. it's textual content.
109
110
  # @param path [Array<String>] The node's "path," i.e. this node's label and the labels of all its ancestors. This node should be reachable by traversing the tree following this path.
110
- # @param node_variant [Symbol] The variant to use for this node. <%= one_of(Primer::OpenProject::TreeView::NODE_VARIANT_OPTIONS) %>
111
+ # @param node_variant [Symbol] The variant to use for this node. <%= one_of(Primer::Alpha::TreeView::NODE_VARIANT_OPTIONS) %>
112
+ # @param sub_tree_component_klass [Class] The class to use for the sub-tree instead of the default <%= link_to_component(Primer::Alpha::TreeView::SubTree) %>
111
113
  # @param expanded [Boolean] Whether or not this sub-tree should be rendered expanded.
112
- # @param select_strategy [Symbol] What should happen when this sub-tree node is checked. <%= one_of(Primer::OpenProject::TreeView::SubTreeNode::SELECT_STRATEGIES) %>
113
- # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::Node) %>.
114
- def initialize(label:, path:, node_variant:, expanded: false, select_strategy: DEFAULT_SELECT_STRATEGY, **system_arguments)
114
+ # @param select_strategy [Symbol] What should happen when this sub-tree node is checked. <%= one_of(Primer::Alpha::TreeView::SubTreeNode::SELECT_STRATEGIES) %>
115
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::Node) %>.
116
+ def initialize(
117
+ label:,
118
+ path:,
119
+ node_variant:,
120
+ sub_tree_component_klass: SubTree,
121
+ expanded: false,
122
+ select_strategy: DEFAULT_SELECT_STRATEGY,
123
+ **system_arguments
124
+ )
115
125
  @label = label
116
126
  @system_arguments = system_arguments
117
127
  @select_strategy = fetch_or_fallback(SELECT_STRATEGIES, select_strategy, DEFAULT_SELECT_STRATEGY)
@@ -123,23 +133,23 @@ module Primer
123
133
 
124
134
  @system_arguments[:data] = merge_data(
125
135
  @system_arguments, {
126
- data: {
127
- target: "tree-view-sub-tree-node.node",
128
- "node-type": "sub-tree"
129
- }
136
+ data: {
137
+ target: "tree-view-sub-tree-node.node",
138
+ "node-type": "sub-tree"
130
139
  }
140
+ }
131
141
  )
132
142
 
133
143
  sub_tree_arguments = @system_arguments.delete(:sub_tree_arguments) || {}
134
144
 
135
- @sub_tree = SubTree.new(
145
+ @sub_tree = sub_tree_component_klass.new(
136
146
  expanded: expanded,
137
147
  path: path,
138
148
  node_variant: node_variant,
139
149
  **sub_tree_arguments
140
150
  )
141
151
 
142
- @node = Primer::OpenProject::TreeView::Node.new(
152
+ @node = Primer::Alpha::TreeView::Node.new(
143
153
  **@system_arguments,
144
154
  path: @sub_tree.path,
145
155
  node_variant: node_variant
@@ -1,10 +1,15 @@
1
- import { TreeViewSubTreeNodeElement } from './tree_view_sub_tree_node_element';
1
+ import { SelectStrategy, TreeViewSubTreeNodeElement } from './tree_view_sub_tree_node_element';
2
2
  import type { TreeViewNodeType, TreeViewCheckedValue, TreeViewNodeInfo } from '../../shared_events';
3
3
  export declare class TreeViewElement extends HTMLElement {
4
4
  #private;
5
+ formInputContainer: HTMLElement;
6
+ formInputPrototype: HTMLInputElement;
5
7
  connectedCallback(): void;
8
+ rootLeafNodes(): NodeListOf<HTMLElement>;
9
+ rootSubTreeNodes(): NodeListOf<TreeViewSubTreeNodeElement>;
6
10
  disconnectedCallback(): void;
7
11
  handleEvent(event: Event): void;
12
+ getFormInputValueForNode(node: Element): string | null;
8
13
  getNodePath(node: Element): string[];
9
14
  getNodeType(node: Element): TreeViewNodeType | null;
10
15
  markCurrentAtPath(path: string[]): void;
@@ -16,13 +21,18 @@ export declare class TreeViewElement extends HTMLElement {
16
21
  uncheckAtPath(path: string[]): void;
17
22
  toggleCheckedAtPath(path: string[]): void;
18
23
  checkedValueAtPath(path: string[]): TreeViewCheckedValue;
24
+ disabledValueAtPath(path: string[]): boolean;
19
25
  nodeAtPath(path: string[], selector?: string): Element | null;
20
26
  subTreeAtPath(path: string[]): TreeViewSubTreeNodeElement | null;
21
27
  leafAtPath(path: string[]): HTMLLIElement | null;
28
+ setNodeCheckedValue(node: Element, value: TreeViewCheckedValue): void;
22
29
  getNodeCheckedValue(node: Element): TreeViewCheckedValue;
30
+ getNodeDisabledValue(node: Element): boolean;
31
+ setNodeDisabledValue(node: Element, disabled: boolean): void;
23
32
  nodeHasCheckBox(node: Element): boolean;
24
33
  nodeHasNativeAction(node: Element): boolean;
25
34
  expandAncestorsForNode(node: HTMLElement): void;
35
+ changeSelectStrategy(newStrategy: SelectStrategy): void;
26
36
  infoFromNode(node: Element, newCheckedValue?: TreeViewCheckedValue): TreeViewNodeInfo | null;
27
37
  }
28
38
  declare global {
@@ -15,8 +15,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
15
15
  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");
16
16
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
17
17
  };
18
- var _TreeViewElement_instances, _TreeViewElement_abortController, _TreeViewElement_autoExpandFrom, _TreeViewElement_eventIsActivation, _TreeViewElement_nodeForEvent, _TreeViewElement_handleNodeEvent, _TreeViewElement_eventIsCheckboxToggle, _TreeViewElement_handleCheckboxToggle, _TreeViewElement_handleNodeActivated, _TreeViewElement_handleNodeFocused, _TreeViewElement_handleNodeKeyboardEvent, _TreeViewElement_setNodeCheckedValue;
19
- import { controller } from '@github/catalyst';
18
+ var _TreeViewElement_instances, _TreeViewElement_abortController, _TreeViewElement_autoExpandFrom, _TreeViewElement_eventIsActivation, _TreeViewElement_nodeForEvent, _TreeViewElement_handleNodeEvent, _TreeViewElement_eventIsCheckboxToggle, _TreeViewElement_handleCheckboxToggle, _TreeViewElement_handleNodeActivated, _TreeViewElement_handleNodeFocused, _TreeViewElement_handleNodeKeyboardEvent;
19
+ import { controller, target } from '@github/catalyst';
20
20
  import { useRovingTabIndex } from './tree_view_roving_tab_index';
21
21
  let TreeViewElement = class TreeViewElement extends HTMLElement {
22
22
  constructor() {
@@ -43,12 +43,53 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
43
43
  }
44
44
  }
45
45
  }).observe(this, { childList: true, subtree: true });
46
+ const updateInputsObserver = new MutationObserver(mutations => {
47
+ if (!this.formInputContainer)
48
+ return;
49
+ // There is another MutationObserver in TreeViewSubTreeNodeElement that manages checking/unchecking
50
+ // nodes based on the component's select strategy. These two observers can conflict and cause infinite
51
+ // looping, so we make sure something actually changed before computing inputs again.
52
+ const somethingChanged = mutations.some(m => {
53
+ if (!(m.target instanceof HTMLElement))
54
+ return false;
55
+ return m.target.getAttribute('aria-checked') !== m.oldValue;
56
+ });
57
+ if (!somethingChanged)
58
+ return;
59
+ const newInputs = [];
60
+ // eslint-disable-next-line custom-elements/no-dom-traversal-in-connectedcallback
61
+ for (const node of this.querySelectorAll('[role=treeitem][aria-checked=true]')) {
62
+ const newInput = this.formInputPrototype.cloneNode();
63
+ newInput.removeAttribute('data-target');
64
+ newInput.removeAttribute('form');
65
+ const payload = {
66
+ path: this.getNodePath(node),
67
+ };
68
+ const inputValue = this.getFormInputValueForNode(node);
69
+ if (inputValue)
70
+ payload.value = inputValue;
71
+ newInput.value = JSON.stringify(payload);
72
+ newInputs.push(newInput);
73
+ }
74
+ this.formInputContainer.replaceChildren(...newInputs);
75
+ });
76
+ updateInputsObserver.observe(this, {
77
+ childList: true,
78
+ subtree: true,
79
+ attributeFilter: ['aria-checked'],
80
+ });
46
81
  // eslint-disable-next-line github/no-then -- We don't want to wait for this to resolve, just get on with it
47
82
  customElements.whenDefined('tree-view-sub-tree-node').then(() => {
48
83
  // depends on TreeViewSubTreeNodeElement#eachAncestorSubTreeNode, which may not be defined yet
49
84
  __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_autoExpandFrom).call(this, this);
50
85
  });
51
86
  }
87
+ rootLeafNodes() {
88
+ return this.querySelectorAll(':scope > ul > li > .TreeViewItemContainer [role=treeitem]');
89
+ }
90
+ rootSubTreeNodes() {
91
+ return this.querySelectorAll(':scope > ul > tree-view-sub-tree-node');
92
+ }
52
93
  disconnectedCallback() {
53
94
  __classPrivateFieldGet(this, _TreeViewElement_abortController, "f").abort();
54
95
  }
@@ -58,6 +99,9 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
58
99
  __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeEvent).call(this, node, event);
59
100
  }
60
101
  }
102
+ getFormInputValueForNode(node) {
103
+ return node.getAttribute('data-value');
104
+ }
61
105
  getNodePath(node) {
62
106
  const rawPath = node.getAttribute('data-path');
63
107
  if (rawPath) {
@@ -101,13 +145,13 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
101
145
  const node = this.nodeAtPath(path);
102
146
  if (!node)
103
147
  return;
104
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'true');
148
+ this.setNodeCheckedValue(node, 'true');
105
149
  }
106
150
  uncheckAtPath(path) {
107
151
  const node = this.nodeAtPath(path);
108
152
  if (!node)
109
153
  return;
110
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'false');
154
+ this.setNodeCheckedValue(node, 'false');
111
155
  }
112
156
  toggleCheckedAtPath(path) {
113
157
  const node = this.nodeAtPath(path);
@@ -128,6 +172,12 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
128
172
  return 'false';
129
173
  return this.getNodeCheckedValue(node);
130
174
  }
175
+ disabledValueAtPath(path) {
176
+ const node = this.nodeAtPath(path);
177
+ if (!node)
178
+ return false;
179
+ return this.getNodeDisabledValue(node);
180
+ }
131
181
  nodeAtPath(path, selector) {
132
182
  const pathStr = JSON.stringify(path);
133
183
  return this.querySelector(`${selector || ''}[data-path="${CSS.escape(pathStr)}"]`);
@@ -141,9 +191,23 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
141
191
  leafAtPath(path) {
142
192
  return this.nodeAtPath(path, '[data-node-type=leaf]');
143
193
  }
194
+ setNodeCheckedValue(node, value) {
195
+ node.setAttribute('aria-checked', value.toString());
196
+ }
144
197
  getNodeCheckedValue(node) {
145
198
  return (node.getAttribute('aria-checked') || 'false');
146
199
  }
200
+ getNodeDisabledValue(node) {
201
+ return node.getAttribute('aria-disabled') === 'true';
202
+ }
203
+ setNodeDisabledValue(node, disabled) {
204
+ if (disabled) {
205
+ node.setAttribute('aria-disabled', 'true');
206
+ }
207
+ else {
208
+ node.removeAttribute('aria-disabled');
209
+ }
210
+ }
147
211
  nodeHasCheckBox(node) {
148
212
  return node.querySelector('.TreeViewItemCheckbox') !== null;
149
213
  }
@@ -160,6 +224,11 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
160
224
  }
161
225
  }
162
226
  }
227
+ changeSelectStrategy(newStrategy) {
228
+ for (const subTreeNode of this.querySelectorAll('tree-view-sub-tree-node')) {
229
+ subTreeNode.changeSelectStrategy(newStrategy);
230
+ }
231
+ }
163
232
  // PRIVATE API METHOD
164
233
  //
165
234
  // This would normally be marked private, but it's called by TreeViewSubTreeNodes
@@ -189,22 +258,22 @@ _TreeViewElement_eventIsActivation = function _TreeViewElement_eventIsActivation
189
258
  return event.type === 'click';
190
259
  };
191
260
  _TreeViewElement_nodeForEvent = function _TreeViewElement_nodeForEvent(event) {
192
- const target = event.target;
193
- const node = target.closest('[role=treeitem]');
261
+ const eventTarget = event.target;
262
+ const node = eventTarget.closest('[role=treeitem]');
194
263
  if (!node)
195
264
  return null;
196
- if (target.closest('.TreeViewItemToggle'))
265
+ if (eventTarget.closest('.TreeViewItemToggle'))
197
266
  return null;
198
- if (target.closest('.TreeViewItemLeadingAction'))
267
+ if (eventTarget.closest('.TreeViewItemLeadingAction'))
199
268
  return null;
200
269
  return node;
201
270
  };
202
271
  _TreeViewElement_handleNodeEvent = function _TreeViewElement_handleNodeEvent(node, event) {
203
272
  if (__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_eventIsCheckboxToggle).call(this, event, node)) {
204
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleCheckboxToggle).call(this, node);
273
+ __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleCheckboxToggle).call(this, event, node);
205
274
  }
206
275
  else if (__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_eventIsActivation).call(this, event)) {
207
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeActivated).call(this, node);
276
+ __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeActivated).call(this, event, node);
208
277
  }
209
278
  else if (event.type === 'focusin') {
210
279
  __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_handleNodeFocused).call(this, node);
@@ -216,19 +285,43 @@ _TreeViewElement_handleNodeEvent = function _TreeViewElement_handleNodeEvent(nod
216
285
  _TreeViewElement_eventIsCheckboxToggle = function _TreeViewElement_eventIsCheckboxToggle(event, node) {
217
286
  return event.type === 'click' && this.nodeHasCheckBox(node);
218
287
  };
219
- _TreeViewElement_handleCheckboxToggle = function _TreeViewElement_handleCheckboxToggle(node) {
220
- // only handle checking of leaf nodes
288
+ _TreeViewElement_handleCheckboxToggle = function _TreeViewElement_handleCheckboxToggle(event, node) {
289
+ if (this.getNodeDisabledValue(node)) {
290
+ event.preventDefault();
291
+ return;
292
+ }
293
+ // only handle checking of leaf nodes, see TreeViewSubTreeNodeElement for the code that
294
+ // handles checking sub tree items.
221
295
  const type = this.getNodeType(node);
222
296
  if (type !== 'leaf')
223
297
  return;
298
+ const checkValue = this.getNodeCheckedValue(node);
299
+ const newCheckValue = checkValue === 'false' ? 'true' : 'false';
300
+ const nodeInfo = this.infoFromNode(node, newCheckValue);
301
+ const checkSuccess = this.dispatchEvent(new CustomEvent('treeViewBeforeNodeChecked', {
302
+ bubbles: true,
303
+ cancelable: true,
304
+ detail: [nodeInfo],
305
+ }));
306
+ if (!checkSuccess)
307
+ return;
224
308
  if (this.getNodeCheckedValue(node) === 'true') {
225
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'false');
309
+ this.setNodeCheckedValue(node, 'false');
226
310
  }
227
311
  else {
228
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'true');
312
+ this.setNodeCheckedValue(node, 'true');
229
313
  }
314
+ this.dispatchEvent(new CustomEvent('treeViewNodeChecked', {
315
+ bubbles: true,
316
+ cancelable: true,
317
+ detail: [nodeInfo],
318
+ }));
230
319
  };
231
- _TreeViewElement_handleNodeActivated = function _TreeViewElement_handleNodeActivated(node) {
320
+ _TreeViewElement_handleNodeActivated = function _TreeViewElement_handleNodeActivated(event, node) {
321
+ if (this.getNodeDisabledValue(node)) {
322
+ event.preventDefault();
323
+ return;
324
+ }
232
325
  // do not emit activation events for buttons and anchors, since it is assumed any activation
233
326
  // behavior for these element types is user- or browser-defined
234
327
  if (!(node instanceof HTMLDivElement))
@@ -262,13 +355,17 @@ _TreeViewElement_handleNodeKeyboardEvent = function _TreeViewElement_handleNodeK
262
355
  switch (event.key) {
263
356
  case ' ':
264
357
  case 'Enter':
358
+ if (this.getNodeDisabledValue(node)) {
359
+ event.preventDefault();
360
+ break;
361
+ }
265
362
  if (this.nodeHasCheckBox(node)) {
266
363
  event.preventDefault();
267
364
  if (this.getNodeCheckedValue(node) === 'true') {
268
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'false');
365
+ this.setNodeCheckedValue(node, 'false');
269
366
  }
270
367
  else {
271
- __classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_setNodeCheckedValue).call(this, node, 'true');
368
+ this.setNodeCheckedValue(node, 'true');
272
369
  }
273
370
  }
274
371
  else if (node instanceof HTMLAnchorElement) {
@@ -278,9 +375,12 @@ _TreeViewElement_handleNodeKeyboardEvent = function _TreeViewElement_handleNodeK
278
375
  break;
279
376
  }
280
377
  };
281
- _TreeViewElement_setNodeCheckedValue = function _TreeViewElement_setNodeCheckedValue(node, value) {
282
- node.setAttribute('aria-checked', value.toString());
283
- };
378
+ __decorate([
379
+ target
380
+ ], TreeViewElement.prototype, "formInputContainer", void 0);
381
+ __decorate([
382
+ target
383
+ ], TreeViewElement.prototype, "formInputPrototype", void 0);
284
384
  TreeViewElement = __decorate([
285
385
  controller
286
386
  ], TreeViewElement);