Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2a819ad
Basic functionality is working
camertron May 30, 2025
22a02fe
Allow TreeView nodes to be disabled
camertron May 31, 2025
b5769b8
Allow FilterableTreeViews to act as form inputs
camertron May 31, 2025
64f173d
Add tests for disabling TreeView nodes
camertron Jun 1, 2025
22a3470
Beginnings of some FilterableTreeView tests
camertron Jun 1, 2025
dab634c
More tests; add highlighting functionality
camertron Jun 2, 2025
4e89028
Refactor highlight code; additional tests; no results messaging
camertron Jun 2, 2025
aa5a65a
Merge branch 'main' into filterable_tree_view
camertron Jun 3, 2025
162f22e
Ok I think this crap is finally working
camertron Jun 4, 2025
ab13f36
Ok, I think checking/unchecking finally works
camertron Jun 5, 2025
b79b47c
Don't include input value if not set
camertron Jun 6, 2025
4c767af
Clean up auto check/uncheck logic
camertron Jun 6, 2025
0f98939
Docs
camertron Jun 6, 2025
e2c3d65
Small docs tweaks
camertron Jun 7, 2025
0329612
Add test for custom filter modes
camertron Jun 7, 2025
9219647
Add changeset
camertron Jun 11, 2025
7544c16
Merge branch 'main' into filterable_tree_view
camertron Jun 11, 2025
2142a9d
Fix URL helper in preview
camertron Jun 11, 2025
ebfe7e9
Generating component snapshots
camertron Jun 11, 2025
619b617
Build
camertron Jun 11, 2025
c420ae5
Add more previews for FilterableTreeView
HDinger Aug 11, 2025
1c7bb7e
Use primer variables for color selection and make sure that the highl…
HDinger Aug 12, 2025
ea8ff09
Make default strings localized
HDinger Aug 12, 2025
fb1a290
Add some tests for behaviour when "sub-items included" is checked
HDinger Aug 12, 2025
e445206
Adapt tests to new localization
HDinger Aug 12, 2025
e1f95d7
Add some tests for form submission
HDinger Aug 12, 2025
2b62126
Merge remote-tracking branch 'origin/main' into filterable_tree_view
HDinger Aug 12, 2025
70ed74d
Generating component snapshots
HDinger Aug 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tough-seas-post.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@openproject/primer-view-components': minor
---

Add the FilterableTreeView component
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
- button "Click me"
- alertdialog "Delete dialog":
- heading "Delete dialog" [level=1]
- 'button "Translation missing: en.button_close"'
- button "Close"
- heading "Delete this item?" [level=2]
- paragraph: Do you want to continue?
- 'button "Translation missing: en.button_cancel"'
- 'button "Translation missing: en.button_delete"'
- button "Cancel"
- button "Delete"
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
- button "Click me"
- alertdialog "Delete dialog":
- heading "Delete dialog" [level=1]
- 'button "Translation missing: en.button_close"'
- button "Close"
- heading "Permanently delete this item?" [level=2]
- paragraph: This action is not reversible. Please proceed with caution.
- checkbox "I understand that this deletion cannot be reversed": "1"
- text: I understand that this deletion cannot be reversed
- 'button "Translation missing: en.button_cancel"'
- 'button "Translation missing: en.button_delete_permanently" [disabled]'
- button "Cancel"
- button "Delete permanently" [disabled]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
- button "Click me"
- dialog "Success dialog":
- heading "Success dialog" [level=1]
- 'button "Translation missing: en.button_close"'
- button "Close"
- heading "Success" [level=2]
- paragraph: Great! Everything worked well.
- 'button "Translation missing: en.button_close"'
- button "Close"
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- list "Filter mode":
- listitem:
- button "Teacher"
- listitem:
- button "All"
- checkbox "Include sub-items": "1"
- text: Include sub-items Filter
- searchbox "Filter"
- button "Clear"
- tree:
- treeitem "Albus Dumbledore" [level=1]
- treeitem "Minerva McGonagall" [level=1]
- treeitem "Severus Snape" [level=1]
- treeitem "Rubeus Hagrid" [level=1]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- list "Filter mode":
- listitem:
- button "Teacher"
- listitem:
- button "All"
- checkbox "Include sub-items": "1"
- text: Include sub-items Filter
- searchbox "Filter"
- button "Clear"
- tree:
- treeitem "Students" [expanded] [level=1]
- group:
- treeitem "Ravenclaw" [expanded] [level=2]
- group:
- treeitem "Luna Lovegood" [level=3]
- treeitem "Slytherin" [expanded] [level=2]
- group:
- treeitem "Draco Malfoy" [level=3]
- treeitem "Hufflepuff" [expanded] [level=2]
- group:
- treeitem "Susan Bones" [level=3]
- treeitem "Gryffindor" [expanded] [level=2]
- group:
- treeitem "Harry Potter" [level=3]
- treeitem "Ronald Weasley" [level=3]
- treeitem "Hermione Granger" [level=3]
- treeitem "Albus Dumbledore" [level=1]
- treeitem "Minerva McGonagall" [level=1]
- treeitem "Severus Snape" [level=1]
- treeitem "Rubeus Hagrid" [level=1]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- list "Filter mode":
- listitem:
- button "All"
- listitem:
- button "Selected"
- checkbox "Include sub-items": "1"
- text: Include sub-items Filter
- searchbox "Filter"
- button "Clear"
- tree:
- treeitem "Students" [expanded] [level=1]
- group:
- treeitem "Ravenclaw" [expanded] [level=2]
- group:
- treeitem "Luna Lovegood" [level=3]
- treeitem "Slytherin" [expanded] [level=2]
- group:
- treeitem "Draco Malfoy" [level=3]
- treeitem "Hufflepuff" [expanded] [level=2]
- group:
- treeitem "Susan Bones" [level=3]
- treeitem "Gryffindor" [expanded] [level=2]
- group:
- treeitem "Harry Potter" [level=3]
- treeitem "Ronald Weasley" [level=3]
- treeitem "Hermione Granger" [level=3]
- treeitem "Albus Dumbledore" [level=1]
- treeitem "Minerva McGonagall" [level=1]
- treeitem "Severus Snape" [level=1]
- treeitem "Rubeus Hagrid" [level=1]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- list "Filter mode":
- listitem:
- button "All"
- listitem:
- button "Selected"
- checkbox "Include sub-items": "1"
- text: Include sub-items Filter
- searchbox "Filter"
- button "Clear"
- tree:
- treeitem "Students" [expanded] [level=1]
- group:
- treeitem "Ravenclaw" [expanded] [level=2]
- group:
- treeitem "Luna Lovegood" [level=3]
- treeitem "Slytherin" [expanded] [level=2]
- group:
- treeitem "Draco Malfoy" [level=3]
- treeitem "Hufflepuff" [expanded] [level=2]
- group:
- treeitem "Susan Bones" [level=3]
- treeitem "Gryffindor" [expanded] [level=2]
- group:
- treeitem "Harry Potter" [level=3]
- treeitem "Ronald Weasley" [level=3]
- treeitem "Hermione Granger" [level=3]
- treeitem "Albus Dumbledore" [level=1]
- treeitem "Minerva McGonagall" [level=1]
- treeitem "Severus Snape" [level=1]
- treeitem "Rubeus Hagrid" [level=1]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- list "Filter mode":
- listitem:
- button "All"
- listitem:
- button "Selected"
- checkbox "Include sub-items": "1"
- text: Include sub-items Filter
- searchbox "Filter"
- button "Clear"
- tree:
- treeitem "Students" [expanded] [level=1]
- group:
- treeitem "Ravenclaw" [expanded] [level=2]
- group:
- treeitem "Luna Lovegood" [level=3]
- treeitem "Slytherin" [expanded] [level=2]
- group:
- treeitem "Draco Malfoy" [level=3]
- treeitem "Hufflepuff" [expanded] [level=2]
- group:
- treeitem "Susan Bones" [level=3]
- treeitem "Gryffindor" [expanded] [level=2]
- group:
- treeitem "Harry Potter" [level=3]
- treeitem "Ronald Weasley" [level=3]
- treeitem "Hermione Granger" [level=3]
- treeitem "Albus Dumbledore" [level=1]
- treeitem "Minerva McGonagall" [level=1]
- treeitem "Severus Snape" [level=1]
- treeitem "Rubeus Hagrid" [level=1]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
- list "Filter mode":
- listitem:
- button "All"
- listitem:
- button "Selected"
- checkbox "Include sub-items": "1"
- text: Include sub-items Filter
- searchbox "Filter"
- button "Clear"
- tree:
- treeitem "Students" [expanded] [level=1]
- group:
- treeitem "Ravenclaw" [expanded] [level=2]
- group:
- treeitem "Luna Lovegood" [level=3]
- treeitem "Slytherin" [expanded] [level=2]
- group:
- treeitem "Draco Malfoy" [level=3]
- treeitem "Hufflepuff" [expanded] [level=2]
- group:
- treeitem "Susan Bones" [level=3]
- treeitem "Gryffindor" [expanded] [level=2]
- group:
- treeitem "Harry Potter" [level=3]
- treeitem "Ronald Weasley" [level=3]
- treeitem "Hermione Granger" [level=3]
- treeitem "Albus Dumbledore" [level=1]
- treeitem "Minerva McGonagall" [level=1]
- treeitem "Severus Snape" [level=1]
- treeitem "Rubeus Hagrid" [level=1]
17 changes: 16 additions & 1 deletion app/components/primer/alpha/segmented_control.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {controller, targets} from '@github/catalyst'

@controller
class SegmentedControlElement extends HTMLElement {
export class SegmentedControlElement extends HTMLElement {
@targets items: HTMLElement[]

connectedCallback() {
Expand All @@ -17,6 +17,21 @@ class SegmentedControlElement extends HTMLElement {

button.closest('li.SegmentedControl-item')?.classList.add('SegmentedControl-item--selected')
button.setAttribute('aria-current', 'true')

this.dispatchEvent(
new CustomEvent('itemActivated', {
bubbles: true,
detail: {
item: button,
checked: false,
value: button.querySelector('.Button-label')?.textContent,
},
}),
)
}

get current(): HTMLElement | null {
return this.querySelector('[aria-current=true]')
}

// Updates the button labels to have a data-content attribute with the text
Expand Down
13 changes: 13 additions & 0 deletions app/components/primer/alpha/stack.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,11 @@
flex-wrap: nowrap;
}

&[data-wrap='reverse'],
&[data-wrap-narrow='reverse'] {
flex-wrap: wrap-reverse;
}

/* @custom-media --veiwportRange-regular */
@media (min-width: 48rem) {
&[data-padding-regular='none'] {
Expand Down Expand Up @@ -203,6 +208,10 @@
&[data-wrap-regular='nowrap'] {
flex-wrap: nowrap;
}

&[data-wrap-regular='reverse'] {
flex-wrap: wrap-reverse;
}
}

/* @custom-media --viewportRange-wide */
Expand Down Expand Up @@ -293,5 +302,9 @@
&[data-wrap-wide='nowrap'] {
flex-wrap: nowrap;
}

&[data-wrap-wide='reverse'] {
flex-wrap: wrap-reverse;
}
}
}
3 changes: 2 additions & 1 deletion app/components/primer/alpha/stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ class WrapArg < Primer::ResponsiveArg
OPTIONS = [
nil,
DEFAULT,
:wrap
:wrap,
:reverse
].freeze

def initialize(values)
Expand Down
28 changes: 28 additions & 0 deletions app/components/primer/open_project/filterable_tree_view.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
<%= render(Primer::Alpha::Stack.new) do %>
<%= render(Primer::Alpha::Stack.new(wrap: :reverse, direction: :horizontal, align: :center)) do %>
<%= render(Primer::Alpha::Stack.new(wrap: :wrap, direction: :horizontal, align: :center)) do %>
<%= render(Primer::Alpha::StackItem.new) do %>
<%= render(@filter_mode_control) %>
<% end %>
<%= render(Primer::Alpha::StackItem.new) do %>
<%= render(@include_sub_items_check_box) do |input| %>
<% input.merge_input_arguments!(form: "") %>
<% end %>
<% end %>
<% end %>
<%= render(Primer::Alpha::StackItem.new(grow: true)) do %>
<%= render(@filter_input) do |input| %>
<%# exclude from form submissions %>
<% input.merge_input_arguments!(form: "") %>
<% end %>
<% end %>
<% end %>
<%= render(Primer::BaseComponent.new(tag: :div, hidden: true, data: { target: "filterable-tree-view.noResultsMessage" })) do %>
<%= render(Primer::OpenProject::TreeView.new) do |tree| %>
<% tree.with_leaf(**@no_results_node_arguments) %>
<% end %>
<% end %>
<%= render(@tree_view) %>
<% end %>
<% end %>
Loading