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,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ class TreeView
6
+ # Renders a loading skeleton for a `TreeView` sub-tree node.
7
+ #
8
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
9
+ # not be used directly.
10
+ class SkeletonLoader < Primer::Component
11
+ # The failure message that appears if loading nodes from the server fails.
12
+ #
13
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::LoadingFailureMessage) %>.
14
+ renders_one :loading_failure_message, lambda { |**system_arguments|
15
+ system_arguments[:retry_button_arguments] ||= {}
16
+ system_arguments[:retry_button_arguments][:data] = merge_data(
17
+ system_arguments[:retry_button_arguments],
18
+ data: { target: "tree-view-sub-tree-node.retryButton" }
19
+ )
20
+
21
+ LoadingFailureMessage.new(**system_arguments)
22
+ }
23
+
24
+ # @param src [String] The URL to fetch nodes from.
25
+ # @param count [Integer] The number of skeleton nodes to render.
26
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::SubTreeContainer) %>.
27
+ def initialize(src:, count: 3, **system_arguments)
28
+ @src = src
29
+ @count = count
30
+
31
+ @container = SubTreeContainer.new(**system_arguments, expanded: true)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,20 @@
1
+ <% unless loading_failure_message? %>
2
+ <% with_loading_failure_message # set the default %>
3
+ <% end %>
4
+
5
+ <%= render(Primer::BaseComponent.new(tag: :"tree-view-include-fragment", src: @src, loading: :lazy, data: { target: "tree-view-sub-tree-node.subTree tree-view-sub-tree-node.includeFragment", path: @container.path.to_json }, hidden: @container.expanded?, accept: "text/fragment+html")) do %>
6
+ <%= render(@container) do %>
7
+ <%= render(Primer::Alpha::TreeView::Node.new(path: [*@container.path, :loader], data: { target: "tree-view-sub-tree-node.loadingIndicator" }, node_variant: :div)) do |node| %>
8
+ <% node.with_text_content { "Loading..." } %>
9
+ <% node.with_leading_visual do %>
10
+ <%= render(Primer::Beta::Spinner.new(size: :small, wrapper_arguments: { classes: "TreeViewItemVisual" })) %>
11
+ <% end %>
12
+ <% end %>
13
+
14
+ <%= render(Primer::Alpha::TreeView::Node.new(path: [*@container.path, :failure_msg], data: { target: "tree-view-sub-tree-node.loadingFailureMessage" }, hidden: true, node_variant: :div)) do |node| %>
15
+ <% node.with_text_content do %>
16
+ <%= loading_failure_message %>
17
+ <% end %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ class TreeView
6
+ # Renders a loading spinner for a `TreeView` sub-tree node.
7
+ #
8
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
9
+ # not be used directly.
10
+ class SpinnerLoader < Primer::Component
11
+ # The failure message that appears if loading nodes from the server fails.
12
+ #
13
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::LoadingFailureMessage) %>.
14
+ renders_one :loading_failure_message, lambda { |**system_arguments|
15
+ system_arguments[:retry_button_arguments] ||= {}
16
+ system_arguments[:retry_button_arguments][:data] = merge_data(
17
+ system_arguments[:retry_button_arguments],
18
+ data: { target: "tree-view-sub-tree-node.retryButton" }
19
+ )
20
+
21
+ LoadingFailureMessage.new(**system_arguments)
22
+ }
23
+
24
+ # @param src [String] The URL to fetch nodes from.
25
+ # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::SubTreeContainer) %>.
26
+ def initialize(src:, **system_arguments)
27
+ @src = src
28
+ @container = SubTreeContainer.new(**system_arguments, expanded: true)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ <% if defer? %>
2
+ <%= loader %>
3
+ <% else %>
4
+ <% unless no_items_message? %>
5
+ <% with_no_items_message { "No items" } # set the default %>
6
+ <% end %>
7
+
8
+ <%= render(@container) do %>
9
+ <% if nodes.empty? %>
10
+ <%= render(Primer::Alpha::TreeView::Node.new(path: path, data: { "no-items": true }, node_variant: :div)) do |node| %>
11
+ <% node.with_text_content do %>
12
+ <%= no_items_message %>
13
+ <% end %>
14
+ <% end %>
15
+ <% else %>
16
+ <% nodes.each do |node| %>
17
+ <%= node %>
18
+ <% end %>
19
+ <% end %>
20
+ <% end %>
21
+ <% end %>
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ class TreeView
6
+ # A `TreeView` sub-tree.
7
+ #
8
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
9
+ # not be used directly.
10
+ class SubTree < Primer::Component
11
+ # @!parse
12
+ # # Adds an leaf node to the tree. Leaf nodes are nodes that do not have children.
13
+ # #
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
+ # def with_leaf(**system_arguments, &block)
17
+ # end
18
+
19
+ # @!parse
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
+ # #
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
+ # def with_sub_tree(**system_arguments, &block)
25
+ # end
26
+
27
+ renders_many :nodes, types: {
28
+ leaf: {
29
+ renders: lambda { |component_klass: LeafNode, label:, **system_arguments|
30
+ component_klass.new(
31
+ **system_arguments,
32
+ node_variant: node_variant,
33
+ path: [*path, label],
34
+ label: label
35
+ )
36
+ },
37
+
38
+ as: :leaf
39
+ },
40
+
41
+ sub_tree: {
42
+ renders: lambda { |component_klass: SubTreeNode, label:, **system_arguments|
43
+ component_klass.new(
44
+ **system_arguments,
45
+ node_variant: node_variant,
46
+ path: [*path, label],
47
+ label: label
48
+ )
49
+ },
50
+
51
+ as: :sub_tree
52
+ }
53
+ }
54
+
55
+ # @!parse
56
+ # # Adds a loader to this sub-tree that displays a spinner animation while nodes are fetched from the server.
57
+ # #
58
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::SpinnerLoader) %>.
59
+ # def with_loading_spinner(**system_arguments, &block)
60
+ # end
61
+
62
+ # @!parse
63
+ # # Adds a loader to this sub-tree that displays a skeleton animation while nodes are fetched from the server.
64
+ # #
65
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::SkeletonLoader) %>.
66
+ # def with_loading_spinner(**system_arguments, &block)
67
+ # end
68
+
69
+ renders_one :loader, types: {
70
+ spinner: {
71
+ renders: lambda { |**system_arguments|
72
+ SpinnerLoader.new(**system_arguments, path: path)
73
+ },
74
+
75
+ as: :loading_spinner
76
+ },
77
+
78
+ skeleton: {
79
+ renders: lambda { |**system_arguments|
80
+ SkeletonLoader.new(**system_arguments, path: path)
81
+ },
82
+
83
+ as: :loading_skeleton
84
+ }
85
+ }
86
+
87
+ # The message to display if this sub-tree contains no children.
88
+ renders_one :no_items_message
89
+
90
+ delegate :path, :expanded?, to: :@container
91
+
92
+ attr_reader :node_variant
93
+
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
+ def initialize(node_variant:, **system_arguments)
97
+ @node_variant = node_variant
98
+
99
+ system_arguments[:data] = merge_data(
100
+ system_arguments,
101
+ { data: { target: "tree-view-sub-tree-node.subTree" } }
102
+ )
103
+
104
+ @container = SubTreeContainer.new(**system_arguments)
105
+ end
106
+
107
+ def defer?
108
+ loader?
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,3 @@
1
+ <%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
2
+ <%= content %>
3
+ <% end %>
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ class TreeView
6
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
7
+ # not be used directly.
8
+ class SubTreeContainer < Primer::Component
9
+ # The path to this node
10
+ #
11
+ # @return [Array<String>]
12
+ attr_reader :path
13
+
14
+ # Whether or not this sub-tree node renders expanded.
15
+ #
16
+ # @return [Boolean]
17
+ attr_reader :expanded
18
+
19
+ alias expanded? expanded
20
+
21
+ # @param path [Array<String>] The path to this node.
22
+ # @param expanded [Boolean] Whether or not this sub-tree node renders expanded.
23
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
24
+ def initialize(path:, expanded: false, **system_arguments)
25
+ @system_arguments = deny_tag_argument(**system_arguments)
26
+ @path = path
27
+ @expanded = expanded
28
+
29
+ @system_arguments[:tag] = :ul
30
+ @system_arguments[:role] = :group
31
+ @system_arguments[:p] = 0
32
+ @system_arguments[:m] = 0
33
+ @system_arguments[:style] = "list-style: none;"
34
+ @system_arguments[:hidden] = !expanded?
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,49 @@
1
+ <tree-view-sub-tree-node>
2
+ <%= render(@node) do |node| %>
3
+ <% if leading_action? %>
4
+ <% node.with_leading_action do %>
5
+ <%= leading_action %>
6
+ <% end %>
7
+ <% end %>
8
+ <% if leading_visual? %>
9
+ <% node.with_leading_visual do %>
10
+ <%= leading_visual %>
11
+ <% end %>
12
+ <% end %>
13
+ <% if trailing_visual? %>
14
+ <% node.with_trailing_visual do %>
15
+ <%= trailing_visual %>
16
+ <% end %>
17
+ <% end %>
18
+
19
+ <% node.with_text_content { @label } %>
20
+
21
+ <% node.with_toggle do %>
22
+ <div
23
+ data-target="tree-view-sub-tree-node.toggleButton"
24
+ class="TreeViewItemToggle TreeViewItemToggleHover TreeViewItemToggleEnd">
25
+ <%= render(
26
+ Primer::Beta::Octicon.new(
27
+ icon: :"chevron-down",
28
+ size: :xsmall,
29
+ data: { target: "tree-view-sub-tree-node.expandedToggleIcon" },
30
+ hidden: !@sub_tree.expanded?,
31
+ style: "pointer-events: none;"
32
+ )
33
+ ) %>
34
+
35
+ <%= render(
36
+ Primer::Beta::Octicon.new(
37
+ icon: :"chevron-right",
38
+ size: :xsmall,
39
+ data: { target: "tree-view-sub-tree-node.collapsedToggleIcon" },
40
+ hidden: @sub_tree.expanded?,
41
+ style: "pointer-events: none;"
42
+ )
43
+ ) %>
44
+ </div>
45
+ <% end %>
46
+
47
+ <%= render(@sub_tree) %>
48
+ <% end %>
49
+ </tree-view-sub-tree-node>
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ class TreeView
6
+ # A `TreeView` sub-tree node.
7
+ #
8
+ # This component is part of the <%= link_to_component(Primer::Alpha::TreeView) %> component and should
9
+ # not be used directly.
10
+ class SubTreeNode < Primer::Component
11
+ DEFAULT_SELECT_STRATEGY = :mixed_descendants
12
+ SELECT_STRATEGIES = [
13
+ :self,
14
+ DEFAULT_SELECT_STRATEGY,
15
+ :descendants
16
+ ]
17
+
18
+ # @!parse
19
+ # # Adds a leading visual icon rendered to the left of the node's label.
20
+ # #
21
+ # # @param label [String] A label describing the visual, displayed only to screen readers.
22
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::Icon) %>.
23
+ # def with_leading_visual_icon(label: nil, **system_arguments, &block)
24
+ # end
25
+
26
+ # @!parse
27
+ # # Adds a pair of leading visual icon rendered to the left of the node's label.
28
+ # #
29
+ # # @param label [String] A label describing the visual, displayed only to screen readers.
30
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::IconPair) %>.
31
+ # def with_leading_visual_icons(label: nil, **system_arguments, &block)
32
+ # end
33
+
34
+ renders_one :leading_visual, types: {
35
+ icon: lambda { |label: nil, **system_arguments|
36
+ merge_system_arguments!(
37
+ aria: { describedby: leading_visual_label_id }
38
+ )
39
+
40
+ Visual.new(
41
+ id: leading_visual_label_id,
42
+ label: label,
43
+ visual: Icon.new(**system_arguments)
44
+ )
45
+ },
46
+
47
+ icons: lambda { |label: nil, **system_arguments|
48
+ merge_system_arguments!(
49
+ aria: { describedby: leading_visual_label_id }
50
+ )
51
+
52
+ system_arguments[:data] = merge_data(
53
+ system_arguments,
54
+ { data: { target: "tree-view-sub-tree-node.iconPair" } }
55
+ )
56
+
57
+ Visual.new(
58
+ id: leading_visual_label_id,
59
+ label: label,
60
+ visual: IconPair.new(
61
+ **system_arguments,
62
+ expanded: @sub_tree.expanded?,
63
+ )
64
+ )
65
+ }
66
+ }
67
+
68
+ # @!parse
69
+ # # Adds a leading action rendered to the left of the node's label and any leading visuals or checkboxes.
70
+ # #
71
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Beta::IconButton) %>.
72
+ # def with_leading_action_button(**system_arguments, &block)
73
+ # end
74
+
75
+ renders_one :leading_action, types: {
76
+ button: lambda { |**system_arguments|
77
+ LeadingAction.new(
78
+ action: Primer::Beta::IconButton.new(
79
+ scheme: :invisible,
80
+ **system_arguments
81
+ )
82
+ )
83
+ }
84
+ }
85
+
86
+ # @!parse
87
+ # # Adds a trailing visual icon rendered to the right of the node's label.
88
+ # #
89
+ # # @param label [String] A label describing the visual, displayed only to screen readers.
90
+ # # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::TreeView::Icon) %>.
91
+ # def with_trailing_visual_icon(label: nil, **system_arguments, &block)
92
+ # end
93
+
94
+ renders_one :trailing_visual, types: {
95
+ icon: lambda { |**system_arguments|
96
+ label = system_arguments.delete(:label)
97
+
98
+ Visual.new(
99
+ id: nil,
100
+ visual: Icon.new(**system_arguments),
101
+ label: label
102
+ )
103
+ }
104
+ }
105
+
106
+ delegate :with_leaf, :with_sub_tree, :with_loading_spinner, :with_loading_skeleton, :nodes, to: :@sub_tree
107
+ delegate :current?, :merge_system_arguments!, to: :@node
108
+
109
+ # @param label [String] The node's label, i.e. it's textual content.
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.
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) %>
113
+ # @param expanded [Boolean] Whether or not this sub-tree should be rendered expanded.
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
+ )
125
+ @label = label
126
+ @system_arguments = system_arguments
127
+ @select_strategy = fetch_or_fallback(SELECT_STRATEGIES, select_strategy, DEFAULT_SELECT_STRATEGY)
128
+
129
+ @system_arguments[:aria] = merge_aria(
130
+ @system_arguments,
131
+ { aria: { expanded: expanded } }
132
+ )
133
+
134
+ @system_arguments[:data] = merge_data(
135
+ @system_arguments, {
136
+ data: {
137
+ target: "tree-view-sub-tree-node.node",
138
+ "node-type": "sub-tree"
139
+ }
140
+ }
141
+ )
142
+
143
+ sub_tree_arguments = @system_arguments.delete(:sub_tree_arguments) || {}
144
+
145
+ @sub_tree = sub_tree_component_klass.new(
146
+ expanded: expanded,
147
+ path: path,
148
+ node_variant: node_variant,
149
+ **sub_tree_arguments
150
+ )
151
+
152
+ @node = Primer::Alpha::TreeView::Node.new(
153
+ **@system_arguments,
154
+ path: @sub_tree.path,
155
+ node_variant: node_variant
156
+ )
157
+
158
+ return if @node.select_variant == :none
159
+
160
+ @node.merge_system_arguments!(
161
+ data: {
162
+ "select-strategy": @select_strategy
163
+ }
164
+ )
165
+ end
166
+
167
+ def render_in(*args, &block)
168
+ super.tap do
169
+ # check this _after_ rendering so @sub_tree's slots are defined
170
+ if @node.select_variant != :none && @sub_tree.defer?
171
+ raise ArgumentError, "TreeView does not currently support select variants for sub-trees loaded asynchronously."
172
+ end
173
+ end
174
+ end
175
+
176
+ private
177
+
178
+ def base_id
179
+ @base_id ||= self.class.generate_id
180
+ end
181
+
182
+ def leading_visual_label_id
183
+ @leading_visual_id ||= "#{base_id}-leading-visual-label"
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,39 @@
1
+ import { TreeViewSubTreeNodeElement } from './tree_view_sub_tree_node_element';
2
+ import type { TreeViewNodeType, TreeViewCheckedValue, TreeViewNodeInfo } from '../../shared_events';
3
+ export declare class TreeViewElement extends HTMLElement {
4
+ #private;
5
+ formInputContainer: HTMLElement;
6
+ formInputPrototype: HTMLInputElement;
7
+ connectedCallback(): void;
8
+ disconnectedCallback(): void;
9
+ handleEvent(event: Event): void;
10
+ getFormInputValueForNode(node: Element): string | null;
11
+ getNodePath(node: Element): string[];
12
+ getNodeType(node: Element): TreeViewNodeType | null;
13
+ markCurrentAtPath(path: string[]): void;
14
+ get currentNode(): HTMLLIElement | null;
15
+ expandAtPath(path: string[]): void;
16
+ collapseAtPath(path: string[]): void;
17
+ toggleAtPath(path: string[]): void;
18
+ checkAtPath(path: string[]): void;
19
+ uncheckAtPath(path: string[]): void;
20
+ toggleCheckedAtPath(path: string[]): void;
21
+ checkedValueAtPath(path: string[]): TreeViewCheckedValue;
22
+ disabledValueAtPath(path: string[]): boolean;
23
+ nodeAtPath(path: string[], selector?: string): Element | null;
24
+ subTreeAtPath(path: string[]): TreeViewSubTreeNodeElement | null;
25
+ leafAtPath(path: string[]): HTMLLIElement | null;
26
+ setNodeCheckedValue(node: Element, value: TreeViewCheckedValue): void;
27
+ getNodeCheckedValue(node: Element): TreeViewCheckedValue;
28
+ getNodeDisabledValue(node: Element): boolean;
29
+ setNodeDisabledValue(node: Element, disabled: boolean): void;
30
+ nodeHasCheckBox(node: Element): boolean;
31
+ nodeHasNativeAction(node: Element): boolean;
32
+ expandAncestorsForNode(node: HTMLElement): void;
33
+ infoFromNode(node: Element, newCheckedValue?: TreeViewCheckedValue): TreeViewNodeInfo | null;
34
+ }
35
+ declare global {
36
+ interface Window {
37
+ TreeViewElement: typeof TreeViewElement;
38
+ }
39
+ }