openproject-primer_view_components 0.85.0 → 0.86.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/styles/primer_view_components.css +1 -1
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/alpha/tree_view/leaf_node.html.erb +5 -0
- data/app/components/primer/alpha/tree_view/leaf_node.rb +18 -0
- data/app/components/primer/alpha/tree_view/node.html.erb +3 -0
- data/app/components/primer/alpha/tree_view/node.rb +10 -0
- data/app/components/primer/alpha/tree_view/sub_tree_node.html.erb +5 -0
- data/app/components/primer/alpha/tree_view/sub_tree_node.rb +18 -0
- data/app/components/primer/alpha/tree_view/trailing_action.html.erb +3 -0
- data/app/components/primer/alpha/tree_view/trailing_action.rb +18 -0
- data/app/components/primer/alpha/tree_view.css +1 -1
- data/app/components/primer/alpha/tree_view.css.json +4 -1
- data/app/components/primer/alpha/tree_view.css.map +1 -1
- data/app/components/primer/alpha/tree_view.pcss +22 -6
- data/app/components/primer/open_project/filterable_tree_view/sub_tree.rb +6 -6
- data/app/components/primer/open_project/filterable_tree_view.css +1 -0
- data/app/components/primer/open_project/filterable_tree_view.css.json +14 -0
- data/app/components/primer/open_project/filterable_tree_view.css.map +1 -0
- data/app/components/primer/open_project/filterable_tree_view.html.erb +26 -14
- data/app/components/primer/open_project/filterable_tree_view.js +294 -5
- data/app/components/primer/open_project/filterable_tree_view.pcss +57 -0
- data/app/components/primer/open_project/filterable_tree_view.rb +58 -10
- data/app/components/primer/open_project/filterable_tree_view.ts +316 -4
- data/app/components/primer/primer.pcss +1 -0
- data/app/controllers/primer/view_components/filterable_tree_view_items_controller.rb +192 -0
- data/app/views/primer/view_components/filterable_tree_view_items/_node.html.erb +38 -0
- data/app/views/primer/view_components/filterable_tree_view_items/async_form_tree.html.erb +9 -0
- data/app/views/primer/view_components/filterable_tree_view_items/index.html.erb +6 -0
- data/config/routes.rb +4 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/previews/primer/alpha/tree_view_preview/leaf_node_playground.html.erb +4 -0
- data/previews/primer/alpha/tree_view_preview.rb +3 -0
- data/previews/primer/open_project/filterable_tree_view_preview/async.html.erb +3 -0
- data/previews/primer/open_project/filterable_tree_view_preview/async_form_input.html.erb +9 -0
- data/previews/primer/open_project/filterable_tree_view_preview/link_nodes.html.erb +18 -0
- data/previews/primer/open_project/filterable_tree_view_preview.rb +23 -2
- data/static/arguments.json +22 -0
- data/static/audited_at.json +1 -0
- data/static/classes.json +9 -0
- data/static/constants.json +9 -0
- data/static/info_arch.json +123 -1
- data/static/previews.json +39 -0
- data/static/statuses.json +1 -0
- metadata +17 -10
|
@@ -126,6 +126,7 @@ module Primer
|
|
|
126
126
|
# @param leading_visual_icon [Symbol] octicon
|
|
127
127
|
# @param leading_action_icon [Symbol] octicon
|
|
128
128
|
# @param trailing_visual_icon [Symbol] octicon
|
|
129
|
+
# @param trailing_action_icon [Symbol] octicon
|
|
129
130
|
# @param select_variant [Symbol] select [multiple, single, none]
|
|
130
131
|
# @param disabled [Boolean] toggle
|
|
131
132
|
def leaf_node_playground(
|
|
@@ -133,6 +134,7 @@ module Primer
|
|
|
133
134
|
leading_visual_icon: nil,
|
|
134
135
|
leading_action_icon: nil,
|
|
135
136
|
trailing_visual_icon: nil,
|
|
137
|
+
trailing_action_icon: nil,
|
|
136
138
|
select_variant: Primer::Alpha::TreeView::Node::DEFAULT_SELECT_VARIANT,
|
|
137
139
|
disabled: false
|
|
138
140
|
)
|
|
@@ -141,6 +143,7 @@ module Primer
|
|
|
141
143
|
leading_visual_icon: leading_visual_icon,
|
|
142
144
|
leading_action_icon: leading_action_icon,
|
|
143
145
|
trailing_visual_icon: trailing_visual_icon,
|
|
146
|
+
trailing_action_icon: trailing_action_icon,
|
|
144
147
|
select_variant: select_variant.to_sym,
|
|
145
148
|
disabled: disabled
|
|
146
149
|
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<%= form_with(url: primer_view_components.generic_form_submission_path(format: :json)) do |f| %>
|
|
2
|
+
<%= render(Primer::Alpha::Stack.new) do %>
|
|
3
|
+
<%= render(Primer::OpenProject::FilterableTreeView.new(
|
|
4
|
+
src: primer_view_components.filterable_tree_view_items_async_form_tree_path(name: "characters"),
|
|
5
|
+
form_arguments: { builder: f, name: "characters" }
|
|
6
|
+
)) %>
|
|
7
|
+
<%= render(Primer::Alpha::SubmitButton.new(name: :submit, scheme: :primary, label: "Submit")) %>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% end %>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<%= render(Primer::OpenProject::FilterableTreeView.new(
|
|
2
|
+
tree_view_arguments: { node_variant: :anchor },
|
|
3
|
+
filter_mode_control_arguments: { hidden: true }
|
|
4
|
+
)) do |tree| %>
|
|
5
|
+
<% tree.with_sub_tree(label: "Cloud Services", select_variant: :none, expanded: expanded, href: "https://en.wikipedia.org/wiki/Cloud_computing", target: "_blank") do |cloud| %>
|
|
6
|
+
<% cloud.with_leaf(label: "OpenProject", select_variant: :none, href: "https://www.openproject.org", target: "_blank") do |node| %>
|
|
7
|
+
<% node.with_trailing_visual_icon(icon: :"link-external") %>
|
|
8
|
+
<% end %>
|
|
9
|
+
|
|
10
|
+
<% cloud.with_leaf(label: "Hetzner", select_variant: :none, href: "https://www.hetzner.com", target: "_blank") do |node| %>
|
|
11
|
+
<% node.with_trailing_visual_icon(icon: :"link-external") %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<% tree.with_leaf(label: "GitHub", select_variant: :none, href: "https://github.com", target: "_blank") do |node| %>
|
|
16
|
+
<% node.with_trailing_visual_icon(icon: :"link-external") %>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% end %>
|
|
@@ -7,7 +7,7 @@ module Primer
|
|
|
7
7
|
# @label Playground
|
|
8
8
|
#
|
|
9
9
|
# @param expanded [Boolean] toggle
|
|
10
|
-
# @param select_variant [Symbol] select [multiple, single]
|
|
10
|
+
# @param select_variant [Symbol] select [multiple, single, none]
|
|
11
11
|
# @param show_checkbox [Boolean] toggle
|
|
12
12
|
# @param show_segmented_control [Boolean] toggle
|
|
13
13
|
def playground(expanded: true, select_variant: :multiple, show_checkbox: true, show_segmented_control: true)
|
|
@@ -31,7 +31,7 @@ module Primer
|
|
|
31
31
|
|
|
32
32
|
# @label Form input
|
|
33
33
|
#
|
|
34
|
-
# @param select_variant [Symbol] select [multiple, single]
|
|
34
|
+
# @param select_variant [Symbol] select [multiple, single, none]
|
|
35
35
|
# @param expanded [Boolean] toggle
|
|
36
36
|
def form_input(select_variant: :multiple, expanded: true)
|
|
37
37
|
render_with_template(locals: {
|
|
@@ -114,6 +114,27 @@ module Primer
|
|
|
114
114
|
})
|
|
115
115
|
end
|
|
116
116
|
|
|
117
|
+
# @label Async (server-side filtering)
|
|
118
|
+
#
|
|
119
|
+
# @param select_variant [Symbol] select [multiple, single, none]
|
|
120
|
+
def async(select_variant: :single)
|
|
121
|
+
render_with_template(locals: {
|
|
122
|
+
select_variant: select_variant.to_sym
|
|
123
|
+
})
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# @label Async form input
|
|
127
|
+
def async_form_input
|
|
128
|
+
render_with_template
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# @label Link nodes
|
|
132
|
+
def link_nodes(expanded: true)
|
|
133
|
+
render_with_template(locals: {
|
|
134
|
+
expanded: coerce_bool(expanded)
|
|
135
|
+
})
|
|
136
|
+
end
|
|
137
|
+
|
|
117
138
|
# @label Hide checkbox
|
|
118
139
|
#
|
|
119
140
|
# @param include_sub_items [Boolean] toggle
|
data/static/arguments.json
CHANGED
|
@@ -3757,6 +3757,22 @@
|
|
|
3757
3757
|
}
|
|
3758
3758
|
]
|
|
3759
3759
|
},
|
|
3760
|
+
{
|
|
3761
|
+
"component": "TreeView::TrailingAction",
|
|
3762
|
+
"status": "alpha",
|
|
3763
|
+
"a11y_reviewed": false,
|
|
3764
|
+
"short_name": "TreeViewTrailingAction",
|
|
3765
|
+
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/alpha/tree_view/trailing_action.rb",
|
|
3766
|
+
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/alpha/tree_view/trailing_action/default/",
|
|
3767
|
+
"parameters": [
|
|
3768
|
+
{
|
|
3769
|
+
"name": "action",
|
|
3770
|
+
"type": "ViewComponent::Base",
|
|
3771
|
+
"default": "N/A",
|
|
3772
|
+
"description": "A component or other renderable to use as the action button etc."
|
|
3773
|
+
}
|
|
3774
|
+
]
|
|
3775
|
+
},
|
|
3760
3776
|
{
|
|
3761
3777
|
"component": "TreeView::Visual",
|
|
3762
3778
|
"status": "alpha",
|
|
@@ -6151,6 +6167,12 @@
|
|
|
6151
6167
|
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/filterable_tree_view.rb",
|
|
6152
6168
|
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/filterable_tree_view/default/",
|
|
6153
6169
|
"parameters": [
|
|
6170
|
+
{
|
|
6171
|
+
"name": "src",
|
|
6172
|
+
"type": "String",
|
|
6173
|
+
"default": "`nil`",
|
|
6174
|
+
"description": "URL of the server endpoint that returns a filtered `<tree-view>` HTML fragment. When set, activates async (server-side) filtering mode. See \"Async loading strategy\" above."
|
|
6175
|
+
},
|
|
6154
6176
|
{
|
|
6155
6177
|
"name": "tree_view_arguments",
|
|
6156
6178
|
"type": "Hash",
|
data/static/audited_at.json
CHANGED
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"Primer::Alpha::TreeView::SubTree": "",
|
|
85
85
|
"Primer::Alpha::TreeView::SubTreeContainer": "",
|
|
86
86
|
"Primer::Alpha::TreeView::SubTreeNode": "",
|
|
87
|
+
"Primer::Alpha::TreeView::TrailingAction": "",
|
|
87
88
|
"Primer::Alpha::TreeView::Visual": "",
|
|
88
89
|
"Primer::Alpha::UnderlineNav": "",
|
|
89
90
|
"Primer::Alpha::UnderlinePanels": "",
|
data/static/classes.json
CHANGED
|
@@ -271,6 +271,15 @@
|
|
|
271
271
|
"DragHandle": [
|
|
272
272
|
"Primer::OpenProject::DragHandle"
|
|
273
273
|
],
|
|
274
|
+
"FilterableTreeViewLayout": [
|
|
275
|
+
"Primer::OpenProject::FilterableTreeView"
|
|
276
|
+
],
|
|
277
|
+
"FilterableTreeViewLoadingSkeleton": [
|
|
278
|
+
"Primer::OpenProject::FilterableTreeView"
|
|
279
|
+
],
|
|
280
|
+
"FilterableTreeViewTreeContainer": [
|
|
281
|
+
"Primer::OpenProject::FilterableTreeView"
|
|
282
|
+
],
|
|
274
283
|
"FormControl": [
|
|
275
284
|
"Primer::Alpha::TextField"
|
|
276
285
|
],
|
data/static/constants.json
CHANGED
|
@@ -852,6 +852,7 @@
|
|
|
852
852
|
"SubTree": "Primer::Alpha::TreeView::SubTree",
|
|
853
853
|
"SubTreeContainer": "Primer::Alpha::TreeView::SubTreeContainer",
|
|
854
854
|
"SubTreeNode": "Primer::Alpha::TreeView::SubTreeNode",
|
|
855
|
+
"TrailingAction": "Primer::Alpha::TreeView::TrailingAction",
|
|
855
856
|
"Visual": "Primer::Alpha::TreeView::Visual"
|
|
856
857
|
},
|
|
857
858
|
"Primer::Alpha::TreeView::Icon": {
|
|
@@ -918,6 +919,9 @@
|
|
|
918
919
|
"descendants"
|
|
919
920
|
]
|
|
920
921
|
},
|
|
922
|
+
"Primer::Alpha::TreeView::TrailingAction": {
|
|
923
|
+
"GeneratedSlotMethods": "Primer::Alpha::TreeView::TrailingAction::GeneratedSlotMethods"
|
|
924
|
+
},
|
|
921
925
|
"Primer::Alpha::TreeView::Visual": {
|
|
922
926
|
"GeneratedSlotMethods": "Primer::Alpha::TreeView::Visual::GeneratedSlotMethods"
|
|
923
927
|
},
|
|
@@ -1820,6 +1824,11 @@
|
|
|
1820
1824
|
"label": "No results"
|
|
1821
1825
|
},
|
|
1822
1826
|
"GeneratedSlotMethods": "Primer::OpenProject::FilterableTreeView::GeneratedSlotMethods",
|
|
1827
|
+
"SUPPORTED_SELECT_VARIANTS": [
|
|
1828
|
+
"multiple",
|
|
1829
|
+
"single",
|
|
1830
|
+
"none"
|
|
1831
|
+
],
|
|
1823
1832
|
"SubTree": "Primer::OpenProject::FilterableTreeView::SubTree"
|
|
1824
1833
|
},
|
|
1825
1834
|
"Primer::OpenProject::FilterableTreeView::SubTree": {
|
data/static/info_arch.json
CHANGED
|
@@ -4610,6 +4610,11 @@
|
|
|
4610
4610
|
"description": null,
|
|
4611
4611
|
"parameters": []
|
|
4612
4612
|
},
|
|
4613
|
+
{
|
|
4614
|
+
"name": "trailing_action",
|
|
4615
|
+
"description": null,
|
|
4616
|
+
"parameters": []
|
|
4617
|
+
},
|
|
4613
4618
|
{
|
|
4614
4619
|
"name": "trailing_visual",
|
|
4615
4620
|
"description": null,
|
|
@@ -4645,6 +4650,11 @@
|
|
|
4645
4650
|
"description": null,
|
|
4646
4651
|
"parameters": []
|
|
4647
4652
|
},
|
|
4653
|
+
{
|
|
4654
|
+
"name": "trailing_action",
|
|
4655
|
+
"description": null,
|
|
4656
|
+
"parameters": []
|
|
4657
|
+
},
|
|
4648
4658
|
{
|
|
4649
4659
|
"name": "trailing_visual",
|
|
4650
4660
|
"description": null,
|
|
@@ -10900,6 +10910,32 @@
|
|
|
10900
10910
|
"previews": [],
|
|
10901
10911
|
"subcomponents": []
|
|
10902
10912
|
},
|
|
10913
|
+
{
|
|
10914
|
+
"fully_qualified_name": "Primer::Alpha::TreeView::TrailingAction",
|
|
10915
|
+
"description": "The trailing action for `TreeView` nodes.\n\nThis component is part of the {{#link_to_component}}Primer::Alpha::TreeView{{/link_to_component}} component and should\nnot be used directly.",
|
|
10916
|
+
"accessibility_docs": null,
|
|
10917
|
+
"is_form_component": false,
|
|
10918
|
+
"is_published": true,
|
|
10919
|
+
"requires_js": false,
|
|
10920
|
+
"component": "TreeView::TrailingAction",
|
|
10921
|
+
"status": "alpha",
|
|
10922
|
+
"a11y_reviewed": false,
|
|
10923
|
+
"short_name": "TreeViewTrailingAction",
|
|
10924
|
+
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/alpha/tree_view/trailing_action.rb",
|
|
10925
|
+
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/alpha/tree_view/trailing_action/default/",
|
|
10926
|
+
"parameters": [
|
|
10927
|
+
{
|
|
10928
|
+
"name": "action",
|
|
10929
|
+
"type": "ViewComponent::Base",
|
|
10930
|
+
"default": "N/A",
|
|
10931
|
+
"description": "A component or other renderable to use as the action button etc."
|
|
10932
|
+
}
|
|
10933
|
+
],
|
|
10934
|
+
"slots": [],
|
|
10935
|
+
"methods": [],
|
|
10936
|
+
"previews": [],
|
|
10937
|
+
"subcomponents": []
|
|
10938
|
+
},
|
|
10903
10939
|
{
|
|
10904
10940
|
"fully_qualified_name": "Primer::Alpha::TreeView::SubTreeContainer",
|
|
10905
10941
|
"description": "This component is part of the {{#link_to_component}}Primer::Alpha::TreeView{{/link_to_component}} component and should\nnot be used directly.",
|
|
@@ -11240,6 +11276,11 @@
|
|
|
11240
11276
|
"description": "Generic leading action slot",
|
|
11241
11277
|
"parameters": []
|
|
11242
11278
|
},
|
|
11279
|
+
{
|
|
11280
|
+
"name": "trailing_action",
|
|
11281
|
+
"description": "Generic trailing action slot",
|
|
11282
|
+
"parameters": []
|
|
11283
|
+
},
|
|
11243
11284
|
{
|
|
11244
11285
|
"name": "leading_visual",
|
|
11245
11286
|
"description": "Generic leading visual slot",
|
|
@@ -11545,6 +11586,11 @@
|
|
|
11545
11586
|
"description": null,
|
|
11546
11587
|
"parameters": []
|
|
11547
11588
|
},
|
|
11589
|
+
{
|
|
11590
|
+
"name": "trailing_action",
|
|
11591
|
+
"description": null,
|
|
11592
|
+
"parameters": []
|
|
11593
|
+
},
|
|
11548
11594
|
{
|
|
11549
11595
|
"name": "trailing_visual",
|
|
11550
11596
|
"description": null,
|
|
@@ -11584,6 +11630,19 @@
|
|
|
11584
11630
|
],
|
|
11585
11631
|
"return_types": []
|
|
11586
11632
|
},
|
|
11633
|
+
{
|
|
11634
|
+
"name": "with_trailing_action_button",
|
|
11635
|
+
"description": "Adds a trailing action rendered to the right of the node's content.",
|
|
11636
|
+
"parameters": [
|
|
11637
|
+
{
|
|
11638
|
+
"name": "system_arguments",
|
|
11639
|
+
"type": "Hash",
|
|
11640
|
+
"default": "N/A",
|
|
11641
|
+
"description": "The arguments accepted by {{#link_to_component}}Primer::Beta::IconButton{{/link_to_component}}."
|
|
11642
|
+
}
|
|
11643
|
+
],
|
|
11644
|
+
"return_types": []
|
|
11645
|
+
},
|
|
11587
11646
|
{
|
|
11588
11647
|
"name": "with_trailing_visual_icon",
|
|
11589
11648
|
"description": "Adds a trailing visual icon rendered to the right of the node's label.",
|
|
@@ -11675,6 +11734,11 @@
|
|
|
11675
11734
|
"description": null,
|
|
11676
11735
|
"parameters": []
|
|
11677
11736
|
},
|
|
11737
|
+
{
|
|
11738
|
+
"name": "trailing_action",
|
|
11739
|
+
"description": null,
|
|
11740
|
+
"parameters": []
|
|
11741
|
+
},
|
|
11678
11742
|
{
|
|
11679
11743
|
"name": "trailing_visual",
|
|
11680
11744
|
"description": null,
|
|
@@ -11733,6 +11797,19 @@
|
|
|
11733
11797
|
],
|
|
11734
11798
|
"return_types": []
|
|
11735
11799
|
},
|
|
11800
|
+
{
|
|
11801
|
+
"name": "with_trailing_action_button",
|
|
11802
|
+
"description": "Adds a trailing action rendered to the right of the node's content.",
|
|
11803
|
+
"parameters": [
|
|
11804
|
+
{
|
|
11805
|
+
"name": "system_arguments",
|
|
11806
|
+
"type": "Hash",
|
|
11807
|
+
"default": "N/A",
|
|
11808
|
+
"description": "The arguments accepted by {{#link_to_component}}Primer::Beta::IconButton{{/link_to_component}}."
|
|
11809
|
+
}
|
|
11810
|
+
],
|
|
11811
|
+
"return_types": []
|
|
11812
|
+
},
|
|
11736
11813
|
{
|
|
11737
11814
|
"name": "with_trailing_visual_icon",
|
|
11738
11815
|
"description": "Adds a trailing visual icon rendered to the right of the node's label.",
|
|
@@ -20273,7 +20350,7 @@
|
|
|
20273
20350
|
},
|
|
20274
20351
|
{
|
|
20275
20352
|
"fully_qualified_name": "Primer::OpenProject::FilterableTreeView",
|
|
20276
|
-
"description": "A TreeView and associated filter controls for searching nested hierarchies.\n\n## Filter controls\n\n`FilterableTreeView`s can be filtered using two controls, both present in the toolbar above the tree:\n\n1. A free-form query string from a text input field.\n2. A `SegmentedControl` with two options (by default):\n 1. The \"Selected\" option causes the component to only show checked nodes, provided they also satisfy the other\n filter criteria described here.\n 2. The \"All\" option causes the component to show all nodes, provided they also satisfy the other filter\n criteria described here.\n\n## Custom filter modes\n\nIn addition to the default filter modes of `'all'` and `'selected'` described above, `FilterableTreeView` supports\nadding custom filter modes. Adding a filter mode will cause its label to appear in the `SegmentedControl` in the\ntoolbar, and will be passed as the third argument to the filter function (see below).\n\nHere's how to add a custom filter mode in addition to the default ones:\n\n```erb\n<%= render(Primer::OpenProject::FilterableTreeView.new) do |tree_view| %>\n <%# remove this line to prevent adding the default modes %>\n <% tree_view.with_default_filter_modes %>\n <% tree_view.with_filter_mode(name: \"Custom\", system_arguments)\n<% end %>\n```\n\n## Filter behavior\n\nBy default, matching node text is identified by looking for an exact substring match, operating on a lowercased\nversion of both the query string and the node text. For more information, and to provide a customized filter\nfunction, please see the section titled \"Customizing the filter function\" below.\n\nNodes that match the filter appear as normal; nodes that do not match are presented as follows:\n\n1. Leaf nodes are hidden.\n2. Sub-tree nodes with no matching children are hidden.\n3. Sub-tree nodes with at least one matching child are disabled but still visible.\n\n## Checking behavior\n\nBy default, checking a node in a `FilterableTreeView` checks only that node (i.e. no child nodes are checked).\nTo aide in checking children in deeply nested or highly populated hierarchies, a third control exists in the\ntoolbar: the \"Include sub-items\" check box. If this feature is turned on, checking sub-tree nodes causes all\nchildren, both leaf and sub-tree nodes, to also be checked recursively. Moreover, turning this feature on will\ncause the children of any previously checked nodes to be checked recursively. Unchecking a node while in\n\"Include sub-items\" mode will restore that sub-tree and all its children to their previously checked state, so as\nnot to permanently override a user's selections. Unchecking the \"Include sub-items\" check box has a similar effect,\ni.e. restores all previous user selections under currently checked sub-trees.\n\n## JavaScript API\n\n`FilterableTreeView` does not yet have an extensive JavaScript API, but this may change in the future as the\ncomponent is further developed to fit additional use-cases.\n\n### Customizing the filter function\n\nThe filter function can be customized by setting the value of the `filterFn` property to a function with the\nfollowing signature:\n\n```typescript\nexport type FilterFn = (node: HTMLElement, query: string, filterMode?: string) => Range[] | null\n```\n\nThis function will be called once for each node in the tree every time filter controls change (i.e. when the\nfilter mode or query string are altered). The function is called with the following arguments:\n\n|Argument |Description |\n|:-----------|:----------------------------------------------------------------|\n|`node` |The HTML node element, i.e. the element with `role=treeitem` set.|\n|`query` |The query string. |\n|`filterMode`|The filter mode, either `'all'` or `'selected'`. |\n\nThe component expects the filter function to return specific values depending on the type of match:\n\n1. No match - return `null`\n2. Match but no highlights (eg. when the query string is empty) - return an empty array\n3. Match with highlights - return a non-empty array of `Range` objects\n\nExample:\n\n```javascript\nconst filterableTreeView = document.querySelector('filterable-tree-view')\nfilterableTreeView.filterFn = (node, query, filterMode) => {\n // custom filter implementation here\n}\n```\n\nYou can read about `Range` objects here: https://developer.mozilla.org/en-US/docs/Web/API/Range.\n\nFor a complete example demonstrating how to implement a working filter function complete with range highlighting,\nsee the default filter function available in the `FilterableTreeViewElement` JavaScript class, which is part of\nthe Primer source code.\n\n### Events\n\nCurrently `FilterableTreeView` does not emit any events aside from the events already emitted by the `TreeView`\ncomponent.",
|
|
20353
|
+
"description": "A TreeView and associated filter controls for searching nested hierarchies.\n\n## Filter controls\n\n`FilterableTreeView`s can be filtered using two controls, both present in the toolbar above the tree:\n\n1. A free-form query string from a text input field.\n2. A `SegmentedControl` with two options (by default):\n 1. The \"Selected\" option causes the component to only show checked nodes, provided they also satisfy the other\n filter criteria described here.\n 2. The \"All\" option causes the component to show all nodes, provided they also satisfy the other filter\n criteria described here.\n\n## Custom filter modes\n\nIn addition to the default filter modes of `'all'` and `'selected'` described above, `FilterableTreeView` supports\nadding custom filter modes. Adding a filter mode will cause its label to appear in the `SegmentedControl` in the\ntoolbar, and will be passed as the third argument to the filter function (see below).\n\nHere's how to add a custom filter mode in addition to the default ones:\n\n```erb\n<%= render(Primer::OpenProject::FilterableTreeView.new) do |tree_view| %>\n <%# remove this line to prevent adding the default modes %>\n <% tree_view.with_default_filter_modes %>\n <% tree_view.with_filter_mode(name: \"Custom\", system_arguments)\n<% end %>\n```\n\n## Filter behavior\n\nBy default, matching node text is identified by looking for an exact substring match, operating on a lowercased\nversion of both the query string and the node text. For more information, and to provide a customized filter\nfunction, please see the section titled \"Customizing the filter function\" below.\n\nNodes that match the filter appear as normal; nodes that do not match are presented as follows:\n\n1. Leaf nodes are hidden.\n2. Sub-tree nodes with no matching children are hidden.\n3. Sub-tree nodes with at least one matching child are disabled but still visible.\n\n## Checking behavior\n\nBy default, checking a node in a `FilterableTreeView` checks only that node (i.e. no child nodes are checked).\nTo aide in checking children in deeply nested or highly populated hierarchies, a third control exists in the\ntoolbar: the \"Include sub-items\" check box. If this feature is turned on, checking sub-tree nodes causes all\nchildren, both leaf and sub-tree nodes, to also be checked recursively. Moreover, turning this feature on will\ncause the children of any previously checked nodes to be checked recursively. Unchecking a node while in\n\"Include sub-items\" mode will restore that sub-tree and all its children to their previously checked state, so as\nnot to permanently override a user's selections. Unchecking the \"Include sub-items\" check box has a similar effect,\ni.e. restores all previous user selections under currently checked sub-trees.\n\n## JavaScript API\n\n`FilterableTreeView` does not yet have an extensive JavaScript API, but this may change in the future as the\ncomponent is further developed to fit additional use-cases.\n\n### Customizing the filter function\n\nThe filter function can be customized by setting the value of the `filterFn` property to a function with the\nfollowing signature:\n\n```typescript\nexport type FilterFn = (node: HTMLElement, query: string, filterMode?: string) => Range[] | null\n```\n\nThis function will be called once for each node in the tree every time filter controls change (i.e. when the\nfilter mode or query string are altered). The function is called with the following arguments:\n\n|Argument |Description |\n|:-----------|:----------------------------------------------------------------|\n|`node` |The HTML node element, i.e. the element with `role=treeitem` set.|\n|`query` |The query string. |\n|`filterMode`|The filter mode, either `'all'` or `'selected'`. |\n\nThe component expects the filter function to return specific values depending on the type of match:\n\n1. No match - return `null`\n2. Match but no highlights (eg. when the query string is empty) - return an empty array\n3. Match with highlights - return a non-empty array of `Range` objects\n\nExample:\n\n```javascript\nconst filterableTreeView = document.querySelector('filterable-tree-view')\nfilterableTreeView.filterFn = (node, query, filterMode) => {\n // custom filter implementation here\n}\n```\n\nYou can read about `Range` objects here: https://developer.mozilla.org/en-US/docs/Web/API/Range.\n\nFor a complete example demonstrating how to implement a working filter function complete with range highlighting,\nsee the default filter function available in the `FilterableTreeViewElement` JavaScript class, which is part of\nthe Primer source code.\n\n### Events\n\nCurrently `FilterableTreeView` does not emit any events aside from the events already emitted by the `TreeView`\ncomponent.\n\n## Async loading strategy\n\nWhen `src` is set on the component, all filter interactions (text input, filter mode changes) trigger a debounced\nserver request instead of client-side filtering. The server is responsible for returning a filtered `<tree-view>`\nHTML fragment that replaces the current tree.\n\n### Behavior\n\n- The full tree is loaded initially from the server via `src`.\n- Each filter input event triggers a debounced (300 ms) request to the server.\n- The server returns a filtered `<tree-view>` element which replaces the existing one.\n- All matching results and their full ancestor hierarchy are expanded automatically.\n- Matching text is highlighted using the CSS Custom Highlight API (or `<mark>` fallback).\n- When the filter is cleared, the tree is replaced with the full (unfiltered) result from\n the server and the expansion state from before the search is restored.\n- Checked nodes are preserved across tree replacements using `data-node-id` attributes.\n- When \"include sub-items\" is active and the tree is filtered, clicking a parent node\n selects ALL its descendants (not just the visible filtered ones). Therefore, \"include_sub_items\" is passed\n to the server, since it holds the only truth about the data.\n\n### Server endpoint\n\nThe server endpoint must return a `<tree-view>` HTML fragment. Each node must have a stable\n`data-node-id` on its `[role=treeitem]` element.\n\n### Usage\n\n```erb\n<%= render(Primer::OpenProject::FilterableTreeView.new(\n src: my_path\n)) %>\n```",
|
|
20277
20354
|
"accessibility_docs": null,
|
|
20278
20355
|
"is_form_component": false,
|
|
20279
20356
|
"is_published": true,
|
|
@@ -20285,6 +20362,12 @@
|
|
|
20285
20362
|
"source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/filterable_tree_view.rb",
|
|
20286
20363
|
"lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/filterable_tree_view/default/",
|
|
20287
20364
|
"parameters": [
|
|
20365
|
+
{
|
|
20366
|
+
"name": "src",
|
|
20367
|
+
"type": "String",
|
|
20368
|
+
"default": "`nil`",
|
|
20369
|
+
"description": "URL of the server endpoint that returns a filtered `<tree-view>` HTML fragment. When set, activates async (server-side) filtering mode. See \"Async loading strategy\" above."
|
|
20370
|
+
},
|
|
20288
20371
|
{
|
|
20289
20372
|
"name": "tree_view_arguments",
|
|
20290
20373
|
"type": "Hash",
|
|
@@ -20403,6 +20486,45 @@
|
|
|
20403
20486
|
]
|
|
20404
20487
|
}
|
|
20405
20488
|
},
|
|
20489
|
+
{
|
|
20490
|
+
"preview_path": "primer/open_project/filterable_tree_view/async",
|
|
20491
|
+
"name": "async",
|
|
20492
|
+
"snapshot": "false",
|
|
20493
|
+
"skip_rules": {
|
|
20494
|
+
"wont_fix": [
|
|
20495
|
+
"region"
|
|
20496
|
+
],
|
|
20497
|
+
"will_fix": [
|
|
20498
|
+
"color-contrast"
|
|
20499
|
+
]
|
|
20500
|
+
}
|
|
20501
|
+
},
|
|
20502
|
+
{
|
|
20503
|
+
"preview_path": "primer/open_project/filterable_tree_view/async_form_input",
|
|
20504
|
+
"name": "async_form_input",
|
|
20505
|
+
"snapshot": "false",
|
|
20506
|
+
"skip_rules": {
|
|
20507
|
+
"wont_fix": [
|
|
20508
|
+
"region"
|
|
20509
|
+
],
|
|
20510
|
+
"will_fix": [
|
|
20511
|
+
"color-contrast"
|
|
20512
|
+
]
|
|
20513
|
+
}
|
|
20514
|
+
},
|
|
20515
|
+
{
|
|
20516
|
+
"preview_path": "primer/open_project/filterable_tree_view/link_nodes",
|
|
20517
|
+
"name": "link_nodes",
|
|
20518
|
+
"snapshot": "false",
|
|
20519
|
+
"skip_rules": {
|
|
20520
|
+
"wont_fix": [
|
|
20521
|
+
"region"
|
|
20522
|
+
],
|
|
20523
|
+
"will_fix": [
|
|
20524
|
+
"color-contrast"
|
|
20525
|
+
]
|
|
20526
|
+
}
|
|
20527
|
+
},
|
|
20406
20528
|
{
|
|
20407
20529
|
"preview_path": "primer/open_project/filterable_tree_view/hide_checkbox",
|
|
20408
20530
|
"name": "hide_checkbox",
|
data/static/previews.json
CHANGED
|
@@ -4502,6 +4502,45 @@
|
|
|
4502
4502
|
]
|
|
4503
4503
|
}
|
|
4504
4504
|
},
|
|
4505
|
+
{
|
|
4506
|
+
"preview_path": "primer/open_project/filterable_tree_view/async",
|
|
4507
|
+
"name": "async",
|
|
4508
|
+
"snapshot": "false",
|
|
4509
|
+
"skip_rules": {
|
|
4510
|
+
"wont_fix": [
|
|
4511
|
+
"region"
|
|
4512
|
+
],
|
|
4513
|
+
"will_fix": [
|
|
4514
|
+
"color-contrast"
|
|
4515
|
+
]
|
|
4516
|
+
}
|
|
4517
|
+
},
|
|
4518
|
+
{
|
|
4519
|
+
"preview_path": "primer/open_project/filterable_tree_view/async_form_input",
|
|
4520
|
+
"name": "async_form_input",
|
|
4521
|
+
"snapshot": "false",
|
|
4522
|
+
"skip_rules": {
|
|
4523
|
+
"wont_fix": [
|
|
4524
|
+
"region"
|
|
4525
|
+
],
|
|
4526
|
+
"will_fix": [
|
|
4527
|
+
"color-contrast"
|
|
4528
|
+
]
|
|
4529
|
+
}
|
|
4530
|
+
},
|
|
4531
|
+
{
|
|
4532
|
+
"preview_path": "primer/open_project/filterable_tree_view/link_nodes",
|
|
4533
|
+
"name": "link_nodes",
|
|
4534
|
+
"snapshot": "false",
|
|
4535
|
+
"skip_rules": {
|
|
4536
|
+
"wont_fix": [
|
|
4537
|
+
"region"
|
|
4538
|
+
],
|
|
4539
|
+
"will_fix": [
|
|
4540
|
+
"color-contrast"
|
|
4541
|
+
]
|
|
4542
|
+
}
|
|
4543
|
+
},
|
|
4505
4544
|
{
|
|
4506
4545
|
"preview_path": "primer/open_project/filterable_tree_view/hide_checkbox",
|
|
4507
4546
|
"name": "hide_checkbox",
|
data/static/statuses.json
CHANGED
|
@@ -84,6 +84,7 @@
|
|
|
84
84
|
"Primer::Alpha::TreeView::SubTree": "alpha",
|
|
85
85
|
"Primer::Alpha::TreeView::SubTreeContainer": "alpha",
|
|
86
86
|
"Primer::Alpha::TreeView::SubTreeNode": "alpha",
|
|
87
|
+
"Primer::Alpha::TreeView::TrailingAction": "alpha",
|
|
87
88
|
"Primer::Alpha::TreeView::Visual": "alpha",
|
|
88
89
|
"Primer::Alpha::UnderlineNav": "alpha",
|
|
89
90
|
"Primer::Alpha::UnderlinePanels": "alpha",
|
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openproject-primer_view_components
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.86.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- GitHub Open Source
|
|
8
8
|
- OpenProject GmbH
|
|
9
|
-
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: actionview
|
|
@@ -73,8 +72,6 @@ dependencies:
|
|
|
73
72
|
- - "<"
|
|
74
73
|
- !ruby/object:Gem::Version
|
|
75
74
|
version: '5.0'
|
|
76
|
-
description:
|
|
77
|
-
email:
|
|
78
75
|
executables: []
|
|
79
76
|
extensions: []
|
|
80
77
|
extra_rdoc_files: []
|
|
@@ -369,6 +366,8 @@ files:
|
|
|
369
366
|
- app/components/primer/alpha/tree_view/sub_tree_container.rb
|
|
370
367
|
- app/components/primer/alpha/tree_view/sub_tree_node.html.erb
|
|
371
368
|
- app/components/primer/alpha/tree_view/sub_tree_node.rb
|
|
369
|
+
- app/components/primer/alpha/tree_view/trailing_action.html.erb
|
|
370
|
+
- app/components/primer/alpha/tree_view/trailing_action.rb
|
|
372
371
|
- app/components/primer/alpha/tree_view/tree_view.d.ts
|
|
373
372
|
- app/components/primer/alpha/tree_view/tree_view.js
|
|
374
373
|
- app/components/primer/alpha/tree_view/tree_view.ts
|
|
@@ -626,9 +625,13 @@ files:
|
|
|
626
625
|
- app/components/primer/open_project/feedback_message.rb
|
|
627
626
|
- app/components/primer/open_project/fieldset.html.erb
|
|
628
627
|
- app/components/primer/open_project/fieldset.rb
|
|
628
|
+
- app/components/primer/open_project/filterable_tree_view.css
|
|
629
|
+
- app/components/primer/open_project/filterable_tree_view.css.json
|
|
630
|
+
- app/components/primer/open_project/filterable_tree_view.css.map
|
|
629
631
|
- app/components/primer/open_project/filterable_tree_view.d.ts
|
|
630
632
|
- app/components/primer/open_project/filterable_tree_view.html.erb
|
|
631
633
|
- app/components/primer/open_project/filterable_tree_view.js
|
|
634
|
+
- app/components/primer/open_project/filterable_tree_view.pcss
|
|
632
635
|
- app/components/primer/open_project/filterable_tree_view.rb
|
|
633
636
|
- app/components/primer/open_project/filterable_tree_view.ts
|
|
634
637
|
- app/components/primer/open_project/filterable_tree_view/sub_tree.rb
|
|
@@ -719,6 +722,7 @@ files:
|
|
|
719
722
|
- app/controllers/primer/view_components/application_controller.rb
|
|
720
723
|
- app/controllers/primer/view_components/auto_check_controller.rb
|
|
721
724
|
- app/controllers/primer/view_components/auto_complete_test_controller.rb
|
|
725
|
+
- app/controllers/primer/view_components/filterable_tree_view_items_controller.rb
|
|
722
726
|
- app/controllers/primer/view_components/form_handler_controller.rb
|
|
723
727
|
- app/controllers/primer/view_components/include_fragment_controller.rb
|
|
724
728
|
- app/controllers/primer/view_components/multi_controller.rb
|
|
@@ -887,6 +891,9 @@ files:
|
|
|
887
891
|
- app/views/primer/view_components/auto_check/_warning_message.html.erb
|
|
888
892
|
- app/views/primer/view_components/auto_complete_test/index.html.erb
|
|
889
893
|
- app/views/primer/view_components/auto_complete_test/no_results.html.erb
|
|
894
|
+
- app/views/primer/view_components/filterable_tree_view_items/_node.html.erb
|
|
895
|
+
- app/views/primer/view_components/filterable_tree_view_items/async_form_tree.html.erb
|
|
896
|
+
- app/views/primer/view_components/filterable_tree_view_items/index.html.erb
|
|
890
897
|
- app/views/primer/view_components/form_handler/form_action.html.erb
|
|
891
898
|
- app/views/primer/view_components/include_fragment/deferred.html.erb
|
|
892
899
|
- app/views/primer/view_components/nav_list_items/index.html.erb
|
|
@@ -1269,6 +1276,8 @@ files:
|
|
|
1269
1276
|
- previews/primer/open_project/feedback_message_preview.rb
|
|
1270
1277
|
- previews/primer/open_project/filterable_tree_view_preview.rb
|
|
1271
1278
|
- previews/primer/open_project/filterable_tree_view_preview/_custom_select_js.html.erb
|
|
1279
|
+
- previews/primer/open_project/filterable_tree_view_preview/async.html.erb
|
|
1280
|
+
- previews/primer/open_project/filterable_tree_view_preview/async_form_input.html.erb
|
|
1272
1281
|
- previews/primer/open_project/filterable_tree_view_preview/custom_checkbox_text.html.erb
|
|
1273
1282
|
- previews/primer/open_project/filterable_tree_view_preview/custom_no_results_text.html.erb
|
|
1274
1283
|
- previews/primer/open_project/filterable_tree_view_preview/custom_segmented_control.html.erb
|
|
@@ -1276,6 +1285,7 @@ files:
|
|
|
1276
1285
|
- previews/primer/open_project/filterable_tree_view_preview/form_input.html.erb
|
|
1277
1286
|
- previews/primer/open_project/filterable_tree_view_preview/hide_checkbox.html.erb
|
|
1278
1287
|
- previews/primer/open_project/filterable_tree_view_preview/hide_segmented_control.html.erb
|
|
1288
|
+
- previews/primer/open_project/filterable_tree_view_preview/link_nodes.html.erb
|
|
1279
1289
|
- previews/primer/open_project/filterable_tree_view_preview/playground.html.erb
|
|
1280
1290
|
- previews/primer/open_project/filterable_tree_view_preview/stress_test.html.erb
|
|
1281
1291
|
- previews/primer/open_project/flex_layout_preview.rb
|
|
@@ -1315,12 +1325,10 @@ files:
|
|
|
1315
1325
|
- static/info_arch.json
|
|
1316
1326
|
- static/previews.json
|
|
1317
1327
|
- static/statuses.json
|
|
1318
|
-
homepage:
|
|
1319
1328
|
licenses:
|
|
1320
1329
|
- MIT
|
|
1321
1330
|
metadata:
|
|
1322
1331
|
allowed_push_host: https://rubygems.org
|
|
1323
|
-
post_install_message:
|
|
1324
1332
|
rdoc_options: []
|
|
1325
1333
|
require_paths:
|
|
1326
1334
|
- lib
|
|
@@ -1328,15 +1336,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
1328
1336
|
requirements:
|
|
1329
1337
|
- - ">="
|
|
1330
1338
|
- !ruby/object:Gem::Version
|
|
1331
|
-
version: 3.
|
|
1339
|
+
version: 3.3.0
|
|
1332
1340
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1333
1341
|
requirements:
|
|
1334
1342
|
- - ">="
|
|
1335
1343
|
- !ruby/object:Gem::Version
|
|
1336
1344
|
version: '0'
|
|
1337
1345
|
requirements: []
|
|
1338
|
-
rubygems_version: 3.
|
|
1339
|
-
signing_key:
|
|
1346
|
+
rubygems_version: 3.6.9
|
|
1340
1347
|
specification_version: 4
|
|
1341
1348
|
summary: ViewComponents of the Primer Design System for OpenProject
|
|
1342
1349
|
test_files: []
|