Skip to content

Commit 31c40f8

Browse files
authored
Dropdown + ellipsis fix (#974)
1 parent 3dd619c commit 31c40f8

File tree

17 files changed

+395
-130
lines changed

17 files changed

+395
-130
lines changed

pgml-dashboard/.editorconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
[*.scss]
3+
indent_style = space
4+
indent_size = 4
5+
6+
[*.js]
7+
indent_style = space
8+
indent_size = 2
9+
10+
[*.rs]
11+
indent_style = space
12+
indent_size = 4
13+
14+
[*.html]
15+
ident_style = space
16+
indent_size = 4
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
.dropdown {
2+
@extend .d-flex;
3+
min-width: 100%;
4+
5+
.dropdown-toggle {
6+
a {
7+
padding: 8px 12px;
8+
}
9+
10+
&:hover {
11+
cursor: pointer;
12+
}
13+
14+
&:after {
15+
content: none;
16+
}
17+
}
18+
19+
.dropdown-menu {
20+
width: 100%;
21+
}
22+
23+
&.expandable {
24+
.dropdown-menu {
25+
width: auto;
26+
min-width: 100%;
27+
}
28+
}
29+
30+
.dropdown-item {
31+
overflow: hidden;
32+
text-overflow: ellipsis;
33+
}
34+
}
35+
36+
.btn-dropdown {
37+
border-radius: $border-radius;
38+
background: #{$gray-700};
39+
color: #{$gray-100};
40+
display: flex;
41+
justify-content: space-between;
42+
font-weight: $font-weight-normal;
43+
44+
--bs-btn-border-color: transparent;
45+
--bs-btn-border-width: 1px;
46+
--bs-btn-hover-border-color: #{$neon-shade-100};
47+
--bs-btn-active-border-color: #{$neon-shade-100};
48+
--bs-btn-active-bg: #{$gray-700};
49+
--bs-btn-active-color: #{$gray-100};
50+
--bs-btn-hover-color: #{$gray-100};
51+
52+
.material-symbols-outlined {
53+
color: #{$neon-shade-100};
54+
}
55+
56+
&:after {
57+
content: None;
58+
}
59+
60+
&.show {
61+
.material-symbols-outlined {
62+
transform: rotate(-180deg);
63+
}
64+
}
65+
66+
.collapase {
67+
width: 100%;
68+
}
69+
70+
.btn-dropdown-text {
71+
overflow: hidden;
72+
text-overflow: ellipsis;
73+
text-align: left;
74+
}
75+
76+
.menu-item {
77+
a {
78+
padding: 8px 12px;
79+
overflow: hidden;
80+
text-overflow: ellipsis;
81+
}
82+
83+
&:hover {
84+
cursor: pointer;
85+
}
86+
87+
&:after {
88+
content: None;
89+
}
90+
}
91+
}
92+
93+
@mixin dropdown-menu($primary-color: null) {
94+
padding: 20px 0px 40px 0px;
95+
overflow-y: auto;
96+
97+
@if ($primary-color) {
98+
background-color: #{$primary-color};
99+
}
100+
}
101+
102+
.dropdown-menu {
103+
@include dropdown-menu($gray-600);
104+
max-height: $dropdown-menu-height;
105+
overflow: hidden;
106+
}
107+
108+
.sub-menu-dropdown {
109+
@include dropdown-menu();
110+
border-radius: 0px;
111+
box-shadow: 1px 1px 8px 0px rgba(0, 0, 0, 0.30);
112+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use crate::components::component;
2+
use crate::components::component::Component;
3+
use sailfish::TemplateOnce;
4+
5+
use crate::components::StaticNavLink;
6+
7+
pub enum DropdownValue {
8+
Icon(Component),
9+
Text(Component),
10+
}
11+
12+
impl Default for DropdownValue {
13+
fn default() -> Self {
14+
DropdownValue::Text("Menu".into())
15+
}
16+
}
17+
18+
#[derive(TemplateOnce, Default)]
19+
#[template(path = "dropdown/template.html")]
20+
pub struct Dropdown {
21+
/// The currently selected value.
22+
value: DropdownValue,
23+
24+
/// The list of dropdown links to render.
25+
links: Vec<StaticNavLink>,
26+
27+
/// Position of the dropdown menu.
28+
offset: String,
29+
30+
/// Whether or not the dropdown is collapsble.
31+
collapsable: bool,
32+
offset_collapsed: String,
33+
34+
/// Where the dropdown menu should appear
35+
menu_position: String,
36+
expandable: bool,
37+
}
38+
39+
impl Dropdown {
40+
pub fn new(links: Vec<StaticNavLink>) -> Self {
41+
let binding = links
42+
.iter()
43+
.filter(|link| link.active)
44+
.collect::<Vec<&StaticNavLink>>();
45+
let active = binding.first();
46+
let value = if let Some(active) = active {
47+
active.name.to_owned()
48+
} else {
49+
"Menu".to_owned()
50+
};
51+
Dropdown {
52+
links,
53+
value: DropdownValue::Text(value.into()),
54+
offset: "0, 10".to_owned(),
55+
offset_collapsed: "68, -44".to_owned(),
56+
menu_position: "".to_owned(),
57+
..Default::default()
58+
}
59+
}
60+
61+
pub fn text(mut self, value: Component) -> Self {
62+
self.value = DropdownValue::Text(value);
63+
self
64+
}
65+
66+
pub fn icon(mut self, icon: Component) -> Self {
67+
self.value = DropdownValue::Icon(icon);
68+
self
69+
}
70+
71+
pub fn collapsable(mut self) -> Self {
72+
self.collapsable = true;
73+
self
74+
}
75+
76+
pub fn menu_end(mut self) -> Self {
77+
self.menu_position = "dropdown-menu-end".to_owned();
78+
self
79+
}
80+
81+
pub fn menu_start(mut self) -> Self {
82+
self.menu_position = "dropdown-menu-start".to_owned();
83+
self
84+
}
85+
86+
pub fn offset(mut self, offset: &str) -> Self {
87+
self.offset = offset.to_owned();
88+
self
89+
}
90+
91+
pub fn offset_collapsed(mut self, offset: &str) -> Self {
92+
self.offset_collapsed = offset.to_owned();
93+
self
94+
}
95+
96+
pub fn expandable(mut self) -> Self {
97+
self.expandable = true;
98+
self
99+
}
100+
}
101+
102+
component!(Dropdown);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
<% use crate::components::dropdown::DropdownValue; %>
3+
4+
<!-- Dropdown component -->
5+
<div class="dropdown <% if expandable { %>expandable<% } %>">
6+
<% if let DropdownValue::Icon(icon) = value { %>
7+
<a
8+
class="topnav-controlls dropdown-toggle"
9+
role="button"
10+
data-bs-toggle="dropdown"
11+
data-bs-offset="<%= offset %>"
12+
href="#"
13+
aria-expanded="false">
14+
<%+ icon %>
15+
</a>
16+
<% } else if let DropdownValue::Text(text) = value { %>
17+
<button
18+
class="horizontal-hide btn btn-dropdown dropdown-toggle <% if collapsable { %> leftnav-collapse-affect <% } %>"
19+
role="button"
20+
data-bs-toggle="dropdown"
21+
data-bs-offset="<%= offset %>"
22+
aria-expanded="false">
23+
<span class="btn-dropdown-text"><%+ text %></span>
24+
<span class="material-symbols-outlined">
25+
expand_more
26+
</span>
27+
</button>
28+
<% } %>
29+
30+
<% if collapsable { %>
31+
<div
32+
class="menu-item horizontal-hide dropdown-toggle collapsed <% if collapsable { %> leftnav-collapse-affect <% } %>"
33+
role="button"
34+
data-bs-toggle="dropdown"
35+
data-bs-offset="<%= offset_collapsed %>"
36+
aria-expanded="false"
37+
>
38+
<a class="d-flex align-items-center justify-content-start gap-2">
39+
<span class="material-symbols-outlined">grid_view</span>
40+
</a>
41+
</div>
42+
<% } %>
43+
44+
<ul class="dropdown-menu <%= menu_position %>">
45+
<% for link in links { %>
46+
<li class="menu-item d-flex align-items-center <% if link.disabled { %>disabled<% } %>">
47+
<% if link.disabled { %>
48+
<a type="button" class="dropdown-item" disabled href="#"><%= link.name %></a>
49+
<% } else { %>
50+
<a type="button" class="dropdown-item" href="<%- link.href %>"><%= link.name %></a>
51+
<% } %>
52+
</li>
53+
<% } %>
54+
</ul>
55+
</div>
56+
<!-- /Dropdown component -->
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.leftnav {
2+
@extend .navbar;
3+
max-width: 260px;
4+
5+
border: none;
6+
align-items: start;
7+
background-color: inherit;
8+
9+
@include media-breakpoint-down(lg) {
10+
background-color: #{$gray-900}
11+
}
12+
}

pgml-dashboard/src/components/left_nav_web_app/template.html

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<% use crate::components::LeftNavMenu; %>
1+
<% use crate::components::{LeftNavMenu, Dropdown}; %>
22
<nav class="leftnav nav-pills h-100" data-controller="extend-bs-collapse" data-extend-bs-collapse-affected-value=".leftnav-collapse-affect">
33
<div class="d-flex flex-column justify-content-between h-100 w-100">
44
<div class="d-flex flex-column">
@@ -11,29 +11,10 @@
1111
</span>
1212
</button>
1313

14-
<div class="dropdown nav-item d-flex w-100 mb-4 show">
15-
<button class="horizontal-hide btn-dropdown dropdown-toggle leftnav-collapse-affect expanded" href="#" role="button" data-bs-toggle="dropdown" data-bs-offset="0, 10" aria-expanded="false">
16-
<%- dropdown_nav.clone().get_active().name %>
17-
<span class="material-symbols-outlined">
18-
expand_more
19-
</span>
20-
</button>
21-
22-
<div class="btn-dropdown-menu-item horizontal-hide m-auto dropdown-toggle leftnav-collapse-affect collapsed" href="#" role="button" data-bs-toggle="dropdown" data-bs-offset="68, -44" aria-expanded="false">
23-
<a class="d-flex align-items-center justify-content-start gap-2">
24-
<span class="material-symbols-outlined">grid_view</span>
25-
</a>
26-
</div>
27-
28-
<ul class="dropdown-menu w-100">
29-
<% for link in dropdown_nav.links { %>
30-
<li class="menu-item d-flex align-items-center">
31-
<a href="<%- link.href %>"><%- link.name %></a>
32-
</li>
33-
<% } %>
34-
</ul>
14+
<div class="mb-4">
15+
<%+ Dropdown::new(dropdown_nav.links).collapsable() %>
3516
</div>
36-
<%+ LeftNavMenu { nav: upper_nav } %>
17+
<%+ LeftNavMenu { nav: upper_nav } %>
3718
</div>
3819
<%+ LeftNavMenu { nav: lower_nav} %>
3920
</div>

pgml-dashboard/src/components/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ pub use breadcrumbs::Breadcrumbs;
1313
pub mod confirm_modal;
1414
pub use confirm_modal::ConfirmModal;
1515

16+
// src/components/dropdown
17+
pub mod dropdown;
18+
pub use dropdown::Dropdown;
19+
1620
// src/components/github_icon
1721
pub mod github_icon;
1822
pub use github_icon::GithubIcon;
@@ -49,6 +53,10 @@ pub use navbar_web_app::NavbarWebApp;
4953
pub mod postgres_logo;
5054
pub use postgres_logo::PostgresLogo;
5155

56+
// src/components/profile_icon
57+
pub mod profile_icon;
58+
pub use profile_icon::ProfileIcon;
59+
5260
// src/components/static_nav
5361
pub mod static_nav;
5462
pub use static_nav::StaticNav;

pgml-dashboard/src/components/navbar_web_app/template.html

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<% use crate::templates::components::GithubIcon; %>
22
<% use crate::templates::components::PostgresLogo; %>
3+
<% use crate::components::{Dropdown, ProfileIcon}; %>
34

45
<div class="fixed-top-nav">
56
<nav class="navbar-web-app horizontal navbar-expand-lg" data-controller="search topnav-web-app">
@@ -57,22 +58,12 @@
5758
</li>
5859

5960
<% if !account_management_nav.links.is_empty() { %>
60-
<li class="d-none d-lg-flex nav-item align-items-center dropdown">
61-
<a class="dropdown-toggle topnav-controlls" href="#" role="button" data-bs-toggle="dropdown" data-bs-offset="10, 15" aria-expanded="false">
62-
<% include!("../../../templates/components/profile_icon.html"); %>
63-
</a>
64-
<!-- Account management for lg and up screens -->
65-
<ul class="dropdown-menu dropdown-menu-end">
66-
<% for item in account_management_nav.links.clone() { %>
67-
<li class="menu-item rounded-0 d-flex align-items-center <% if item.disabled { %>disabled<% } %>">
68-
<a class="<% if item.disabled { %>disabled<% } %>" <% if item.disabled { %>
69-
href="" disabled <% } else { %>
70-
href="<%- item.href %>"<% } %>>
71-
<%- item.name %>
72-
</a>
73-
</li>
74-
<% } %>
75-
</ul>
61+
<li class="d-none d-lg-flex nav-item align-items-center">
62+
<%+
63+
Dropdown::new(account_management_nav.links.clone())
64+
.icon(ProfileIcon::new().into())
65+
.expandable()
66+
%>
7667
</li>
7768
<li class="nav-item d-flex d-lg-none align-items-center">
7869
<a class="nav-link p-lg-0" data-bs-toggle="collapse" data-bs-target=".horizontal-collapse">Account Management</a>

0 commit comments

Comments
 (0)