avo 4.0.0.beta.53 → 4.0.0.beta.54
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/Gemfile.lock +1 -1
- data/app/assets/builds/avo/application.css +45 -0
- data/app/assets/stylesheets/css/sidebar.css +54 -0
- data/app/components/avo/sidebar/link_component.html.erb +4 -22
- data/app/components/avo/sidebar/link_component.rb +25 -40
- data/lib/avo/version.rb +1 -1
- metadata +2 -7
- data/public/avo-assets/avo.base.css +0 -13385
- data/public/avo-assets/avo.base.js +0 -1201
- data/public/avo-assets/avo.base.js.map +0 -7
- data/public/avo-assets/late-registration.js +0 -2
- data/public/avo-assets/late-registration.js.map +0 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 594a52eeb31089a89bb1d453f2a0400921b4ea02bb4838ac8f507710404799d9
|
|
4
|
+
data.tar.gz: 2af844241c1661f13b19d6b7e66faf8c9c6027ff41385c1c4decb2cc3555d692
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52a5240edde338e7dfbc019b3fd232c35f92b400a36914aaf0c8a8a84b6f1134e316668c7ca772f41739455231f16cd152347b900829f4cf97382ab5f8580983
|
|
7
|
+
data.tar.gz: 780e6a097c479994b88273b1df76e2415eac0bbbeff6a9badfeaa3f6f07c114f30d1d7c3be3f244f1944b0851efc06efb0cd950c5726f6d1766abf458b3c3691
|
data/Gemfile.lock
CHANGED
|
@@ -2311,6 +2311,9 @@
|
|
|
2311
2311
|
.bg-gray-100 {
|
|
2312
2312
|
background-color: var(--color-gray-100);
|
|
2313
2313
|
}
|
|
2314
|
+
.bg-gray-100\! {
|
|
2315
|
+
background-color: var(--color-gray-100) !important;
|
|
2316
|
+
}
|
|
2314
2317
|
.bg-gray-500 {
|
|
2315
2318
|
background-color: var(--color-gray-500);
|
|
2316
2319
|
}
|
|
@@ -11644,6 +11647,48 @@ tag.tagify__tag {
|
|
|
11644
11647
|
border-block-end: 2px solid var(--sidebar-link-active-background);
|
|
11645
11648
|
border-end-start-radius: 2px;
|
|
11646
11649
|
}
|
|
11650
|
+
.sidebar-subitem:hover, .sidebar-subitem:has(~ .sidebar-subitem:hover) {
|
|
11651
|
+
position: relative;
|
|
11652
|
+
}
|
|
11653
|
+
.sidebar-subitem:has(~ .sidebar-subitem:hover)::before {
|
|
11654
|
+
content: '';
|
|
11655
|
+
position: absolute;
|
|
11656
|
+
top: calc(var(--spacing) * 0);
|
|
11657
|
+
bottom: calc(var(--spacing) * 0);
|
|
11658
|
+
inset-inline-start: -10px;
|
|
11659
|
+
width: auto;
|
|
11660
|
+
height: auto;
|
|
11661
|
+
border-inline-start: 2px solid var(--sidebar-link-active-background);
|
|
11662
|
+
border-block-end: none;
|
|
11663
|
+
border-end-start-radius: 0;
|
|
11664
|
+
}
|
|
11665
|
+
.sidebar-subitem:hover::before {
|
|
11666
|
+
content: '';
|
|
11667
|
+
position: absolute;
|
|
11668
|
+
top: calc(var(--spacing) * 0);
|
|
11669
|
+
inset-inline-start: -10px;
|
|
11670
|
+
height: 50%;
|
|
11671
|
+
width: 10px;
|
|
11672
|
+
border-inline-start: 2px solid var(--sidebar-link-active-background);
|
|
11673
|
+
border-block-end: 2px solid var(--sidebar-link-active-background);
|
|
11674
|
+
border-end-start-radius: 2px;
|
|
11675
|
+
}
|
|
11676
|
+
.sidebar-subitem:hover:has(~ .sidebar-subitem--bar-active)::before {
|
|
11677
|
+
top: calc(var(--spacing) * 0);
|
|
11678
|
+
bottom: calc(var(--spacing) * 0);
|
|
11679
|
+
height: auto;
|
|
11680
|
+
width: auto;
|
|
11681
|
+
border-block-end: none;
|
|
11682
|
+
border-end-start-radius: 0;
|
|
11683
|
+
}
|
|
11684
|
+
.sidebar-subitem:hover:has(~ .sidebar-subitem--bar-active)::after {
|
|
11685
|
+
content: '';
|
|
11686
|
+
position: absolute;
|
|
11687
|
+
top: calc(50% - 1px);
|
|
11688
|
+
inset-inline-start: -10px;
|
|
11689
|
+
width: 10px;
|
|
11690
|
+
border-block-end: 2px solid var(--sidebar-link-active-background);
|
|
11691
|
+
}
|
|
11647
11692
|
.sidebar-profile {
|
|
11648
11693
|
display: flex;
|
|
11649
11694
|
align-items: center;
|
|
@@ -235,6 +235,60 @@
|
|
|
235
235
|
border-end-start-radius: 2px;
|
|
236
236
|
}
|
|
237
237
|
|
|
238
|
+
/* Hover preview: redraw the full connector path down to the hovered subitem,
|
|
239
|
+
mirroring the active styling. Every item above it gets a vertical line; the
|
|
240
|
+
hovered item gets the L-shape, or a T-shape when the active item sits below
|
|
241
|
+
it (so the line continues past it). The preview is faint (0.6) only when it
|
|
242
|
+
extends below the active item — at or above the active item it stays solid. */
|
|
243
|
+
.sidebar-subitem:hover,
|
|
244
|
+
.sidebar-subitem:has(~ .sidebar-subitem:hover) {
|
|
245
|
+
@apply relative;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Vertical line for every item above the hovered one */
|
|
249
|
+
.sidebar-subitem:has(~ .sidebar-subitem:hover)::before {
|
|
250
|
+
content: '';
|
|
251
|
+
@apply absolute top-0 bottom-0;
|
|
252
|
+
inset-inline-start: -10px;
|
|
253
|
+
width: auto;
|
|
254
|
+
height: auto;
|
|
255
|
+
border-inline-start: 2px solid var(--sidebar-link-active-background);
|
|
256
|
+
border-block-end: none;
|
|
257
|
+
border-end-start-radius: 0;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* L-shape: endpoint at the hovered item */
|
|
261
|
+
.sidebar-subitem:hover::before {
|
|
262
|
+
content: '';
|
|
263
|
+
@apply absolute top-0;
|
|
264
|
+
inset-inline-start: -10px;
|
|
265
|
+
height: 50%;
|
|
266
|
+
width: 10px;
|
|
267
|
+
border-inline-start: 2px solid var(--sidebar-link-active-background);
|
|
268
|
+
border-block-end: 2px solid var(--sidebar-link-active-background);
|
|
269
|
+
border-end-start-radius: 2px;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/* T-shape: when the active item is below the hovered one, the line must
|
|
273
|
+
continue down past it — full vertical line (top + bottom) with a branch to
|
|
274
|
+
the right (three endings) instead of the L-shape endpoint. */
|
|
275
|
+
.sidebar-subitem:hover:has(~ .sidebar-subitem--bar-active)::before {
|
|
276
|
+
@apply top-0 bottom-0;
|
|
277
|
+
height: auto;
|
|
278
|
+
width: auto;
|
|
279
|
+
border-block-end: none;
|
|
280
|
+
border-end-start-radius: 0;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.sidebar-subitem:hover:has(~ .sidebar-subitem--bar-active)::after {
|
|
284
|
+
content: '';
|
|
285
|
+
@apply absolute;
|
|
286
|
+
top: calc(50% - 1px);
|
|
287
|
+
inset-inline-start: -10px;
|
|
288
|
+
width: 10px;
|
|
289
|
+
border-block-end: 2px solid var(--sidebar-link-active-background);
|
|
290
|
+
}
|
|
291
|
+
|
|
238
292
|
/* ================================================ */
|
|
239
293
|
/* Sidebar Profile — SidebarProfileComponent */
|
|
240
294
|
/* BEM: .sidebar-profile (block) */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<% if @path.present? %>
|
|
2
|
-
<%= link_caller.send link_method, @path, class:
|
|
3
|
-
<% if
|
|
2
|
+
<%= link_caller.send link_method, @path, class: root_css_class, active: @active, target: @target, data: link_data, disabled: @disabled, "aria-disabled": @disabled, **@args do %>
|
|
3
|
+
<% if show_icon? %>
|
|
4
4
|
<span class="sidebar-link__icon-wrapper sidebar-icon <%= 'sidebar-link__icon-wrapper--placeholder' if link_icon.blank? %>">
|
|
5
5
|
<%= helpers.svg link_icon, class: "sidebar-link__icon sidebar-icon" if link_icon.present? %>
|
|
6
6
|
</span>
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
<% end %>
|
|
16
16
|
<% end %>
|
|
17
17
|
<% else %>
|
|
18
|
-
<%= content_tag :div, class:
|
|
19
|
-
<% if
|
|
18
|
+
<%= content_tag :div, class: root_css_class, active: @active, target: @target, data: @data do %>
|
|
19
|
+
<% if show_icon? %>
|
|
20
20
|
<span class="sidebar-link__icon-wrapper sidebar-icon <%= 'sidebar-link__icon-wrapper--placeholder' if link_icon.blank? %>">
|
|
21
21
|
<%= helpers.svg link_icon, class: "sidebar-link__icon sidebar-icon" if link_icon.present? %>
|
|
22
22
|
</span>
|
|
@@ -25,21 +25,3 @@
|
|
|
25
25
|
<span><%= @label %></span>
|
|
26
26
|
<% end %>
|
|
27
27
|
<% end %>
|
|
28
|
-
|
|
29
|
-
<% if @items.present? && parent_link_active? %>
|
|
30
|
-
<div class="sidebar-subitem__items">
|
|
31
|
-
<% @items.each_with_index do |item, index| %>
|
|
32
|
-
<% if item.path.present? %>
|
|
33
|
-
<%= link_caller.send link_method, item.path, class: "sidebar-subitem #{subitem_bar_class(index)}", active: @active, target: item.target, data: subitem_data(item), disabled: @disabled, "aria-disabled": @disabled, **item.args do %>
|
|
34
|
-
<span><%= item.try(:label).presence || item.try(:name).presence %></span>
|
|
35
|
-
|
|
36
|
-
<%= hotkey_badge(item.hotkey, class: "ms-auto") if item.try(:hotkey).present? %>
|
|
37
|
-
<% end %>
|
|
38
|
-
<% else %>
|
|
39
|
-
<%= content_tag :div, class: "sidebar-subitem #{subitem_bar_class(index)}", active: @active, target: item.target, data: subitem_data(item) do %>
|
|
40
|
-
<span><%= item.try(:label).presence || item.try(:name).presence %></span>
|
|
41
|
-
<% end %>
|
|
42
|
-
<% end %>
|
|
43
|
-
<% end %>
|
|
44
|
-
</div>
|
|
45
|
-
<% end %>
|
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
require "view_component/version"
|
|
4
4
|
|
|
5
|
+
# A single sidebar link (leaf). `variant: :default` or `:subitem`. Knows nothing
|
|
6
|
+
# about menus; callers pass the path, label and resolved `active` (a match mode
|
|
7
|
+
# like :inclusive, or a boolean to force it).
|
|
5
8
|
class Avo::Sidebar::LinkComponent < Avo::BaseComponent
|
|
6
9
|
prop :label
|
|
7
10
|
prop :path
|
|
8
11
|
prop :active, default: :inclusive do |value|
|
|
9
|
-
value
|
|
12
|
+
value.is_a?(String) ? value.to_sym : value
|
|
10
13
|
end
|
|
11
14
|
prop :target do |value|
|
|
12
15
|
value&.to_sym
|
|
@@ -15,15 +18,31 @@ class Avo::Sidebar::LinkComponent < Avo::BaseComponent
|
|
|
15
18
|
prop :icon
|
|
16
19
|
prop :reserve_icon_space, default: false
|
|
17
20
|
prop :args, kind: :**, default: {}.freeze
|
|
18
|
-
prop :items
|
|
19
21
|
prop :hotkey, default: nil
|
|
22
|
+
prop :variant, default: :default
|
|
23
|
+
prop :bar_class, default: ""
|
|
20
24
|
|
|
21
|
-
def
|
|
22
|
-
|
|
25
|
+
def subitem?
|
|
26
|
+
@variant == :subitem
|
|
23
27
|
end
|
|
24
28
|
|
|
25
|
-
def
|
|
26
|
-
|
|
29
|
+
def root_css_class
|
|
30
|
+
return "sidebar-link" unless subitem?
|
|
31
|
+
|
|
32
|
+
["sidebar-subitem", @bar_class].reject(&:blank?).join(" ")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Sub-items don't show icons (for now); top-level links do.
|
|
36
|
+
def show_icon?
|
|
37
|
+
return false if subitem?
|
|
38
|
+
|
|
39
|
+
@reserve_icon_space || link_icon.present?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def link_data
|
|
43
|
+
return @data if @hotkey.blank?
|
|
44
|
+
|
|
45
|
+
@data.merge(hotkey: @hotkey)
|
|
27
46
|
end
|
|
28
47
|
|
|
29
48
|
def is_external?
|
|
@@ -54,41 +73,7 @@ class Avo::Sidebar::LinkComponent < Avo::BaseComponent
|
|
|
54
73
|
end
|
|
55
74
|
end
|
|
56
75
|
|
|
57
|
-
def parent_link_active?
|
|
58
|
-
return false if @path.blank?
|
|
59
|
-
helpers.is_active_link?(@path, @active)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
76
|
def link_icon
|
|
63
77
|
@icon
|
|
64
78
|
end
|
|
65
|
-
|
|
66
|
-
def active_item_index
|
|
67
|
-
return @active_item_index if defined?(@active_item_index)
|
|
68
|
-
|
|
69
|
-
@active_item_index = @items&.index do |item|
|
|
70
|
-
item.path.present? && helpers.is_active_link?(item.path, @active)
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def subitem_bar_class(index)
|
|
75
|
-
active_idx = active_item_index
|
|
76
|
-
return "" if active_idx.nil?
|
|
77
|
-
|
|
78
|
-
if index == active_idx
|
|
79
|
-
"sidebar-subitem--bar-active"
|
|
80
|
-
elsif index < active_idx
|
|
81
|
-
"sidebar-subitem--bar-pass"
|
|
82
|
-
else
|
|
83
|
-
""
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
private
|
|
88
|
-
|
|
89
|
-
def build_link_data(data, hotkey)
|
|
90
|
-
return data if hotkey.blank?
|
|
91
|
-
|
|
92
|
-
data.merge(hotkey: hotkey)
|
|
93
|
-
end
|
|
94
79
|
end
|
data/lib/avo/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: avo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.0.0.beta.
|
|
4
|
+
version: 4.0.0.beta.54
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adrian Marin
|
|
@@ -1168,11 +1168,6 @@ files:
|
|
|
1168
1168
|
- lib/generators/model_generator.rb
|
|
1169
1169
|
- lib/generators/rails/avo_resource_generator.rb
|
|
1170
1170
|
- lib/tasks/avo_tasks.rake
|
|
1171
|
-
- public/avo-assets/avo.base.css
|
|
1172
|
-
- public/avo-assets/avo.base.js
|
|
1173
|
-
- public/avo-assets/avo.base.js.map
|
|
1174
|
-
- public/avo-assets/late-registration.js
|
|
1175
|
-
- public/avo-assets/late-registration.js.map
|
|
1176
1171
|
- tailwind.custom.js
|
|
1177
1172
|
homepage: https://avohq.io
|
|
1178
1173
|
licenses:
|
|
@@ -1199,7 +1194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
1199
1194
|
- !ruby/object:Gem::Version
|
|
1200
1195
|
version: '0'
|
|
1201
1196
|
requirements: []
|
|
1202
|
-
rubygems_version: 4.0.
|
|
1197
|
+
rubygems_version: 4.0.6
|
|
1203
1198
|
specification_version: 4
|
|
1204
1199
|
summary: Admin panel framework and Content Management System for Ruby on Rails.
|
|
1205
1200
|
test_files: []
|