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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 552669c50574f942f2c964d3c10b75668dbb8cf2507163a8a37cface6ecc0ad2
4
- data.tar.gz: 873ce280034687360210f7c53ae0d82adc7eb33667b154c4621dd49cf378a63f
3
+ metadata.gz: 594a52eeb31089a89bb1d453f2a0400921b4ea02bb4838ac8f507710404799d9
4
+ data.tar.gz: 2af844241c1661f13b19d6b7e66faf8c9c6027ff41385c1c4decb2cc3555d692
5
5
  SHA512:
6
- metadata.gz: 16478d42830c984df2bbaf614656233a50f8c362ca94a2816bb67e9f6effdb809b065dc5bf6fb2aac217bcb9844024b9c8545339acb916cc3ae20e43c38bb865
7
- data.tar.gz: dd22172efd7269ad49ba7909d4b5bb4cdb19f0de2b2105e6447d0ece93d047b704124f49dda711ad01e3ebb5477b2b71b6fbf8aa4e15a0d91a127090bef2231d
6
+ metadata.gz: 52a5240edde338e7dfbc019b3fd232c35f92b400a36914aaf0c8a8a84b6f1134e316668c7ca772f41739455231f16cd152347b900829f4cf97382ab5f8580983
7
+ data.tar.gz: 780e6a097c479994b88273b1df76e2415eac0bbbeff6a9badfeaa3f6f07c114f30d1d7c3be3f244f1944b0851efc06efb0cd950c5726f6d1766abf458b3c3691
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avo (4.0.0.beta.53)
4
+ avo (4.0.0.beta.54)
5
5
  actionview (>= 6.1)
6
6
  active_link_to
7
7
  activerecord (>= 6.1)
@@ -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: "sidebar-link", active: @active, target: @target, data: link_data, disabled: @disabled, "aria-disabled": @disabled, **@args do %>
3
- <% if @reserve_icon_space || link_icon.present? %>
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: "sidebar-link", active: @active, target: @target, data: @data do %>
19
- <% if @reserve_icon_space || link_icon.present? %>
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&.to_sym
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 link_data
22
- build_link_data(@data, @hotkey)
25
+ def subitem?
26
+ @variant == :subitem
23
27
  end
24
28
 
25
- def subitem_data(item)
26
- build_link_data(item.data, item.hotkey)
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
@@ -1,3 +1,3 @@
1
1
  module Avo
2
- VERSION = "4.0.0.beta.53" unless const_defined?(:VERSION)
2
+ VERSION = "4.0.0.beta.54" unless const_defined?(:VERSION)
3
3
  end
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.53
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.9
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: []