keystone_ui 0.39.0 → 0.41.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b11fa4104f5668547e8efeff23c90f69f4c3d1b7374103c33d7dc2c208363acb
4
- data.tar.gz: 719716203afcd39869e402674d72a6bf8f1e5f4e7fce163a76c3429ae2bc77e2
3
+ metadata.gz: fff79f2588c403bbbb1d39b9fec8075955b0f758019fdea442d1dbc081750f99
4
+ data.tar.gz: f92a6ccfa5f383ccc81952c008c8d3dcd59d61906b36d62de4bb9186a3bfcd58
5
5
  SHA512:
6
- metadata.gz: b4849b26d1df9c8a45c7721fa966569e6d0f556780b5139a479a73e08c0602ce1db0eab5d4f8bfedcf5a30301cc4d1bba3cffdb0bf82e91a65a3d87c9fdb575c
7
- data.tar.gz: 8fdb709bfbf187d4792a76c5057ebec69651fb5d4ba2e5b7a6b527b5e0ae68f437689896a492ec390f46ddc7d330fd3e00e2946588f41932d85bf82e790104e3
6
+ metadata.gz: f61c6841e06dcb1fed471c93fbfb41f7655b32e44348ea45df84d961c9b735b051f6e40232738e4df478ea34dac3e6a0c48c8172c2367ddb7f90c292fafdb6cf
7
+ data.tar.gz: d319f7e7a1782535045369da6220ba4dfe0c9fad7a7b15ec8132dddd23b75e69943881df988275cef18b3c41c898afca053d4d2592b3e7e8b091b5acab993e02
@@ -4,15 +4,22 @@
4
4
  <% sidebar = capture do %>
5
5
  <nav class="<%= SIDEBAR_CLASSES %>">
6
6
  <% if logo? %>
7
- <div><%= logo %></div>
7
+ <div class="<%= SIDEBAR_LOGO_CLASSES %>"><%= logo %></div>
8
8
  <% end %>
9
9
  <% groups.each do |group| %>
10
- <div class="<%= SIDEBAR_GROUP_CLASSES %>">
11
- <p class="<%= sidebar_group_label_classes(group) %>"><%= group.label %></p>
12
- <% group.tabs.each do |tab| %>
13
- <a class="<%= sidebar_tab_classes(tab) %>" href="<%= tab.href %>"><%= tab.label %></a>
14
- <% end %>
15
- </div>
10
+ <% if group.standalone %>
11
+ <% tab = group.tabs.first %>
12
+ <a class="<%= sidebar_tab_classes(tab) %>" href="<%= tab.href %>"><%= tab.label %></a>
13
+ <% else %>
14
+ <details class="<%= SIDEBAR_GROUP_CLASSES %>"<%= " open" if group.active %>>
15
+ <summary class="<%= sidebar_group_label_classes(group) %>"><%= group.label %></summary>
16
+ <div class="<%= SIDEBAR_GROUP_TABS_CLASSES %>">
17
+ <% group.tabs.each do |tab| %>
18
+ <a class="<%= sidebar_tab_classes(tab) %>" href="<%= tab.href %>"><%= tab.label %></a>
19
+ <% end %>
20
+ </div>
21
+ </details>
22
+ <% end %>
16
23
  <% end %>
17
24
  <% if menus? %>
18
25
  <div class="<%= SIDEBAR_MENUS_CLASSES %>"><%= menus %></div>
@@ -25,6 +32,7 @@
25
32
  <%= sidebar unless sidebar_first? %>
26
33
  </div>
27
34
  <% else %>
35
+ <div>
28
36
  <div class="<%= TOP_BAR_CLASSES %>">
29
37
  <%= render Keystone::Ui::NavbarComponent.new(sticky: false) do |navbar| %>
30
38
  <% if logo? %>
@@ -32,9 +40,14 @@
32
40
  <% end %>
33
41
  <% navbar.with_desktop_links do %>
34
42
  <% groups.each do |group| %>
35
- <%= render Keystone::Ui::NavDropdownComponent.new(title: group.label, area: group.label, active: group.active) do %>
36
- <% group.tabs.each do |tab| %>
37
- <%= render Keystone::Ui::NavItemComponent.new(label: tab.label, href: tab.href, active: tab.active) %>
43
+ <% if group.standalone %>
44
+ <% tab = group.tabs.first %>
45
+ <%= render Keystone::Ui::NavItemComponent.new(label: tab.label, href: tab.href, active: tab.active) %>
46
+ <% else %>
47
+ <%= render Keystone::Ui::NavDropdownComponent.new(title: group.label, area: group.label, active: group.active) do %>
48
+ <% group.tabs.each do |tab| %>
49
+ <%= render Keystone::Ui::NavItemComponent.new(label: tab.label, href: tab.href, active: tab.active) %>
50
+ <% end %>
38
51
  <% end %>
39
52
  <% end %>
40
53
  <% end %>
@@ -45,4 +58,5 @@
45
58
  <% end %>
46
59
  </div>
47
60
  <%= content %>
61
+ </div>
48
62
  <% end %>
@@ -8,11 +8,17 @@ module Keystone
8
8
  TOP_BAR_CLASSES = "hidden lg:block sticky top-0 z-40"
9
9
  SIDEBAR_ROW_CLASSES = "lg:flex"
10
10
  SIDEBAR_CLASSES = "ks-sidebar hidden lg:flex lg:sticky lg:top-0 lg:h-screen shrink-0 overflow-y-auto"
11
+ SIDEBAR_LOGO_CLASSES = "ks-sidebar-logo"
11
12
  SIDEBAR_GROUP_CLASSES = "flex flex-col"
12
13
  SIDEBAR_GROUP_LABEL_CLASSES = "ks-sidebar-group-label"
14
+ SIDEBAR_GROUP_TABS_CLASSES = "ks-sidebar-group-tabs"
13
15
  SIDEBAR_TAB_CLASSES = "ks-sidebar-tab"
14
16
  ACTIVE_CLASS = "active"
15
- SIDEBAR_MENUS_CLASSES = "mt-auto"
17
+ SIDEBAR_MENUS_CLASSES = [
18
+ "mt-auto [&_[data-dropdown-target=menu]]:static [&_[data-controller~=dropdown]]:flex-wrap [&_[data-dropdown-target=menu]]:basis-full",
19
+ "[&_[data-dropdown-target=menu].hidden]:block [&_[data-dropdown-target=menu].hidden]:h-0 [&_[data-dropdown-target=menu].hidden]:overflow-hidden",
20
+ "[&_[data-dropdown-target=menu].hidden]:my-0 [&_[data-dropdown-target=menu].hidden]:py-0 [&_[data-dropdown-target=menu].hidden]:invisible"
21
+ ].join(" ")
16
22
  SIDEBAR_CONTENT_CLASSES = "min-w-0 flex-1"
17
23
  SIDEBAR_PLACEMENTS = %w[left right].freeze
18
24
 
@@ -31,6 +31,12 @@ module KeystoneUi
31
31
  @navigation_groups << group
32
32
  end
33
33
 
34
+ def navigation_tab(key, label:, href:, permitted:)
35
+ group = NavigationGroup.new(label, standalone: true)
36
+ group.tab(key, label: label, href: href, permitted: permitted)
37
+ @navigation_groups << group
38
+ end
39
+
34
40
  def supplied_look(view)
35
41
  look_supplier&.call(view)&.to_s
36
42
  end
@@ -10,11 +10,16 @@ module KeystoneUi
10
10
 
11
11
  attr_reader :label, :tabs
12
12
 
13
- def initialize(label)
13
+ def initialize(label, standalone: false)
14
14
  @label = label
15
+ @standalone = standalone
15
16
  @tabs = []
16
17
  end
17
18
 
19
+ def standalone?
20
+ @standalone
21
+ end
22
+
18
23
  def tabs_permitted_for(view)
19
24
  tabs.select { |tab| tab.permitted.call(view) }
20
25
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module KeystoneUi
4
- VERSION = "0.39.0"
4
+ VERSION = "0.41.0"
5
5
  end
@@ -4,7 +4,7 @@ require "keystone_ui/navigation_order"
4
4
 
5
5
  module KeystoneUi
6
6
  class VisibleNavigation
7
- Group = Struct.new(:label, :tabs, :active, keyword_init: true)
7
+ Group = Struct.new(:label, :tabs, :active, :standalone, keyword_init: true)
8
8
  Tab = Struct.new(:label, :href, :active, keyword_init: true)
9
9
 
10
10
  def initialize(declared_groups, view:, saved_order:, current_tab:)
@@ -28,7 +28,7 @@ module KeystoneUi
28
28
 
29
29
  def visible_group(group, tabs)
30
30
  visible_tabs = tabs.map { |tab| visible_tab(tab) }
31
- Group.new(label: group.label, tabs: visible_tabs, active: visible_tabs.any?(&:active))
31
+ Group.new(label: group.label, tabs: visible_tabs, active: visible_tabs.any?(&:active), standalone: group.standalone?)
32
32
  end
33
33
 
34
34
  def visible_tab(tab)
@@ -197,7 +197,10 @@ two exceptions: `ui_page`'s `padding:` treats any value other than `:none` as
197
197
  it goes around `yield`. It draws the tabs the app declares with
198
198
  `config.navigation_group` as a top bar of menus from `lg:` up, then the
199
199
  content, and below `lg:` it draws only the content. It leaves out tabs
200
- whose permission check fails and groups with no tab left.
200
+ whose permission check fails and groups with no tab left. A tab declared
201
+ outside any group with `config.navigation_tab` is drawn as a plain link
202
+ in the top bar and as a plain tab with no group label in the sidebar,
203
+ which does not open or close.
201
204
  - Inside its block, `navigation.with_logo do ... end` puts the app's logo at
202
205
  the left of the top bar, and `navigation.with_menus do ... end` puts menus
203
206
  such as the account menu at its right, so the layout draws no second bar.
@@ -206,8 +209,15 @@ two exceptions: `ui_page`'s `padding:` treats any value other than `:none` as
206
209
  - When the preference supplied for `:navigation` holds
207
210
  `{ "placement" => "left" }` or `"right"`, it draws a sidebar on that side
208
211
  from `lg:` up instead, with each group's label above its tabs, the logo at
209
- its top and the menus at its bottom. Any other placement draws the top
210
- bar. An `"order"` list of `{ "group" => label, "tabs" => [tab key strings] }`
212
+ its top and the menus at its bottom. A menu there opens in place: the
213
+ `data-dropdown-target="menu"` panel inside a `data-controller="dropdown"`
214
+ element drops onto its own line below its button inside the sidebar, even
215
+ when the app's own CSS positions it absolutely, as long as that CSS sits
216
+ in a layer below Tailwind's utilities such as `components`. A closed
217
+ panel (the `hidden` class) stays invisible and out of the tab order but
218
+ still counts toward the sidebar's width, so opening a menu never
219
+ changes the sidebar's width. Any other
220
+ placement draws the top bar, whose menus still open as dropdowns. An `"order"` list of `{ "group" => label, "tabs" => [tab key strings] }`
211
221
  entries draws the named groups and tabs first, in that order, then the
212
222
  rest in declared order, ignoring names no longer declared.
213
223
  - When the app sets `config.current_tab_supplier`, the tab whose key it
@@ -31,6 +31,8 @@ built on ViewComponent; hook it in before building any screen with those helpers
31
31
  saves to, and the navigation's placement under the key `:navigation`),
32
32
  `navigation_group` (a labelled group of desktop tabs that the navigation
33
33
  helper draws, each tab declared with `tab key, label:, href:, permitted:`),
34
+ `navigation_tab` (a single desktop tab outside any group, declared with
35
+ `navigation_tab key, label:, href:, permitted:`),
34
36
  `current_tab_supplier` (a callable that supplies the key of the declared tab
35
37
  the current page belongs to, so the navigation marks it and its group
36
38
  active),
@@ -324,6 +326,11 @@ built on ViewComponent; hook it in before building any screen with those helpers
324
326
  `href:`, when two tabs share a key, or when a group has no tabs. Drawing
325
327
  the declared groups in the layout is done with the navigation helper,
326
328
  which belongs to `keystone_ui-develop`.
329
+ - `navigation_tab key, label:, href:, permitted:` — declares one tab
330
+ outside any group, such as a Console or Clients tab, in its place among
331
+ the groups. The navigation helper draws it as a plain link in the top bar
332
+ and as a plain tab with no group label in the sidebar. A saved `"order"`
333
+ names it under `"group"` by its label.
327
334
  - `current_tab_supplier` — a callable that receives the view and returns the
328
335
  key of the declared tab the current page belongs to, or `nil`.
329
336
  The navigation shows that tab and its group as active in the top bar and
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keystone_ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.39.0
4
+ version: 0.41.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tyler Schneider
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 0.14.0
18
+ version: 0.16.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: 0.14.0
25
+ version: 0.16.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: view_component
28
28
  requirement: !ruby/object:Gem::Requirement